Amalan Terbaik dalam Pengaturcaraan TypeScript
Artikel ini menerangkan amalan terbaik dalam pengaturcaraan TypeScript.
Panduan ini menerangkan amalan terbaik yang praktikal untuk memanfaatkan jenis dalam TypeScript bagi mengurangkan pepijat dan menulis kod yang lebih mudah dibaca.
YouTube Video
Amalan Terbaik dalam Pengaturcaraan TypeScript
Manfaat terbesar TypeScript ialah 'mencegah pepijat melalui jenis dan menjelaskan niat kod'.
Amalan terbaik bukan sekadar peraturan tetapi satu set prinsip untuk menulis kod yang selamat, mudah dibaca, dan mudah diselenggara. Di bawah, kami memperkenalkan amalan terbaik TypeScript yang biasa digunakan beserta contoh praktikal.
Elakkan menggunakan any dan sentiasa berikan takrifan jenis yang bermakna
Pertama, mari kita lihat aspek 'mengelakkan penggunaan any dan memberikan jenis yang bermakna.'.
any mematikan pemeriksaan jenis sepenuhnya, yang menafikan tujuan penggunaan TypeScript. Daripada menggunakan any hanya untuk memastikan sesuatu berfungsi, adalah penting untuk menyediakan jenis yang sejelas mungkin.
1// Bad
2function parse(data: any) {
3 return data.value;
4}Kod ini boleh menerima apa-apa nilai, jadi ralat semasa berjalan tidak dapat dielakkan.
1// Good
2type ParsedData = {
3 value: string;
4};
5
6function parse(data: ParsedData): string {
7 return data.value;
8}Dengan mentakrifkan jenis, anda menjelaskan niat input dan output serta meningkatkan keselamatan.
Sentiasa definisikan struktur objek secara jelas dengan menggunakan type atau interface.
Seterusnya, mari kita lihat aspek 'sentiasa mentakrifkan struktur objek secara jelas menggunakan type atau interface.'.
Jika anda menggunakan objek secara ad hoc, strukturnya boleh menjadi tidak jelas. Sentiasa ekstrak jenis untuk kebolehgunaan semula dan penyelenggaraan.
1// Bad
2function createUser(user: { name: string; age: number }) {
3 console.log(user.name);
4}Walaupun dalam bahagian kecil kod, adalah penting untuk membiasakan diri memisahkan jenis-jenis (types).
1// Good
2type User = {
3 name: string;
4 age: number;
5};
6
7function createUser(user: User): void {
8 console.log(user.name);
9}Dengan menamakan jenis, pemahaman terhadap keseluruhan asas kod menjadi lebih mudah.
Gunakan jenis gabungan (union types) untuk mewakili semua kemungkinan keadaan secara tepat.
Jika anda menggunakan jenis string atau number secara mentah untuk syarat, nilai yang tidak dijangka boleh terlepas. Dengan menggunakan jenis gabungan (union types), anda boleh mewakili hanya keadaan-keadaan yang dibenarkan pada peringkat jenis.
1// Bad
2function setStatus(status: string) {
3 console.log(status);
4}Dalam kod ini, rentetan yang tidak bermakna atau nilai yang salah tidak dapat dikesan semasa masa kompilasi.
1// Good
2type Status = "idle" | "loading" | "success" | "error";
3
4function setStatus(status: Status): void {
5 console.log(status);
6}Dengan menggunakan jenis gabungan, anda boleh menyingkirkan 'keadaan mustahil' dengan lebih dipercayai semasa masa kompilasi. Akibatnya, keselamatan cawangan bersyarat dan kebolehpercayaan kod akan meningkat.
Uruskan null dan undefined secara jelas.
Seterusnya, mari kita lihat aspek 'mengendalikan null dan undefined secara jelas.'.
Dalam TypeScript, adalah penting untuk menyatakan kemungkinan ketiadaan nilai dalam jenis. Jika anda membiarkan perkara tidak jelas, ia boleh membawa kepada ralat semasa berjalan.
1type User = {
2 name: string;
3 email?: string;
4};email mungkin tidak wujud, jadi anda harus mengendalikannya dengan anggapan tersebut.
1function printEmail(user: User): void {
2 if (user.email) {
3 console.log(user.email);
4 }
5}Sentiasa periksa nilai pilihan sebelum menggunakannya.
Gunakan pengesahan jenis (as) hanya sebagai pilihan terakhir.
Seterusnya, mari kita lihat aspek 'tidak menggunakan type assertions secara berlebihan.'.
Penegasan jenis (type assertions) secara sementara melangkaui pemeriksaan jenis TypeScript untuk mengisytiharkan, 'Saya tahu nilai ini adalah daripada jenis ini.'. Penggunaan berlebihan akan menjejaskan keselamatan jenis.
1// Bad
2const value = input as string;Dalam kod ini, walaupun nilai sebenar bukan rentetan, tiada ralat berlaku, yang boleh menyebabkan ralat semasa runtime. Seperti yang ditunjukkan dalam kod berikut, pilih untuk memeriksa dengan selamat menggunakan pengawal jenis (type guards) terlebih dahulu.
1// Good
2function isString(value: unknown): value is string {
3 return typeof value === "string";
4}
5
6if (isString(input)) {
7 console.log(input.toUpperCase());
8}Pengawal jenis ialah mekanisme untuk menentukan jenis dengan selamat semasa memeriksa nilai sebenar. Dengan mengutamakan pengawal jenis berbanding penegasan jenis, anda boleh mencegah ralat semasa runtime dengan lebih mudah.
Jangan terlalu bergantung pada inferens jenis untuk jenis pulangan.
Seterusnya, mari kita lihat aspek 'tidak terlalu bergantung kepada inference untuk jenis pulangan.'.
Inferens jenis dalam TypeScript adalah kuat, tetapi adalah lebih selamat untuk menentukan secara jelas jenis pulangan bagi fungsi awam. Ini meminimumkan potensi kesan dari perubahan masa depan.
1// Bad
2function sum(a: number, b: number) {
3 return a + b;
4}Nyatakan niat anda dengan jelas walaupun dalam fungsi yang kecil.
1// Good
2function sum(a: number, b: number): number {
3 return a + b;
4}Menulis jenis pulangan meningkatkan kestabilan API anda.
Kendalikan input dengan selamat dengan menggunakan unknown.
Seterusnya, mari kita lihat aspek 'menerima input luar dengan selamat menggunakan unknown.'.
Untuk input luaran seperti API, JSON, atau input pengguna, gunakan unknown dan bukannya any. Dengan berbuat demikian, anda memastikan semua nilai disahkan, sekali gus mengekalkan keselamatan jenis.
1// Bad
2function handleResponse(data: any) {
3 console.log(data.id);
4}Berikut cara untuk mengesahkan jenis dengan unknown.
1// Good
2function handleResponse(data: unknown): void {
3 if (
4 typeof data === "object" &&
5 data !== null &&
6 "id" in data
7 ) {
8 console.log((data as { id: number }).id);
9 }
10}unknown tidak boleh digunakan secara langsung; ia adalah jenis yang memerlukan pengesahan. Ia sangat berkesan apabila mengendalikan input luaran.
Tingkatkan pengekspresian dengan menggabungkan jenis kecil.
Seterusnya, mari kita lihat aspek 'meningkatkan kejelasan dengan menggabungkan jenis-jenis kecil.'.
Mentakrifkan jenis yang besar sekaligus mengurangkan kebolehbacaan dan kemudahan penyelenggaraan. Bahagikan jenis anda kepada unit bermakna dan gabungkan mengikut keperluan.
1type Id = number;
2
3type UserProfile = {
4 id: Id;
5 name: string;
6};
7
8type UserWithStatus = UserProfile & {
9 status: "active" | "inactive";
10};Menganggap jenis sebagai komponen membantu mengatur reka bentuk anda.
type dan interface
Kelebihan interface
type dan interface kedua-duanya boleh mentakrifkan jenis, tetapi kegunaan dan ciri-cirinya berbeza. Dengan menggunakannya untuk peranan yang sesuai, niat definisi jenis anda menjadi lebih jelas.
1// Bad
2type User = {
3 id: number;
4 name: string;
5};
6
7type AdminUser = {
8 id: number;
9 name: string;
10 role: "admin";
11};Jika anda menduplikasi bahagian biasa seperti ini, kod anda menjadi mudah rosak ketika berlaku perubahan.
1// Good
2interface User {
3 id: number;
4 name: string;
5}
6
7interface AdminUser extends User {
8 role: "admin";
9}interface sangat sesuai untuk reka bentuk yang melibatkan peluasan (extends) dan paling sesuai untuk menyatakan 'bentuk' objek.
Kelebihan type
Sebaliknya, type lebih ekspresif dan sesuai untuk mengendalikan jenis gabungan dan persilangan.
1// Good
2type Status = "idle" | "loading" | "success" | "error";
3
4type ApiResponse<T> =
5 | { status: "success"; data: T }
6 | { status: "error"; message: string };type sangat sesuai untuk menyatakan status, pilihan, dan gabungan.
Garis panduan untuk memilih antara type dan interface
Sebagai panduan umum, gunakan interface untuk struktur dan kontrak objek, dan type apabila anda memerlukan keupayaan pernyataan jenis, gabungan atau operasi jenis.
Kedua-duanya berfungsi hampir sama, tetapi adalah penting untuk memilih berdasarkan tujuan kewujudan jenis tersebut.
Anggap jenis anda sebagai dokumentasi.
Akhir sekali, mari kita lihat aspek 'menulis jenis sebagai dokumentasi.'.
Definisi jenis yang baik menyampaikan lebih banyak maklumat daripada apa-apa komen sekalipun. Adalah penting untuk mencapai keadaan di mana 'spesifikasi boleh difahami hanya dengan melihat pada jenis-jenisnya.'.
1type ApiError = {
2 code: number;
3 message: string;
4 retryable: boolean;
5};Dengan cara ini, salah satu kekuatan utama TypeScript ialah takrifan jenis boleh berfungsi sebagai sejenis dokumen spesifikasi.
Ringkasan
Amalan terbaik TypeScript bukan tentang menjadi terlalu ketat. Intinya adalah untuk menjelaskan niat melalui jenis dan menulis kod yang tahan terhadap perubahan.
Dengan mengumpul peraturan kecil dalam pembangunan harian, anda boleh mencapai kesan jangka panjang seperti 'semakan yang lebih mudah', 'kurang pepijat', dan 'pemahaman yang lebih baik untuk diri anda pada masa hadapan dan orang lain.'.
Mula-mula, dengan berfikir 'bagaimana saya boleh menyatakan ini dengan jenis?', anda akan menulis kod berkualiti tinggi dalam gaya TypeScript.
Anda boleh mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Sila lihat juga saluran YouTube kami.