Bagaimana Typcript mengecewakan saya dan apakah itu layak?



Sebelum memulai, saya ingin menyebutkan bahwa saya adalah penggemar TypeScript. Ini adalah bahasa pemrograman utama saya untuk proyek front-end pada Bereaksi dan untuk setiap pekerjaan backend yang saya lakukan di Node. Saya sepenuhnya untuk naskah, tetapi ada saat-saat yang mengganggu saya dan yang ingin saya ceritakan artikel ini.

Saya menulis secara eksklusif pada TypeScript selama tiga tahun terakhir untuk banyak perusahaan yang berbeda, jadi menurut saya, TypeScript setidaknya melakukan sesuatu dengan benar atau menutup kebutuhan tertentu.

Terlepas dari ketidaksempurnaannya, TypeScript memasuki frontend pengembangan arus utama dan menempati urutan ketujuh dalam daftar bahasa pemrograman paling populer menurut laporan keterampilan pengembang HackerRank .

Setiap tim pengembang, baik besar maupun kecil, menulis dalam TypeScript atau tidak, selalu layak untuk keamanan:

  • Pastikan bahwa unit test yang ditulis dengan baik mencakup kode sebanyak mungkin dalam produksi.
  • Gunakan pemrograman pasangan: sepasang mata ekstra akan membantu menangkap hal-hal yang lebih serius daripada hanya kesalahan sintaksis
  • Secara kualitatif membangun proses peninjauan kode dan mengidentifikasi kesalahan yang tidak dapat ditemukan mesin
  • Gunakan linter - seperti eslint

Meskipun TypeScript menambahkan tingkat keamanan tambahan di atas semua ini, tetapi menurut saya, sangat jauh di belakang bahasa lain dalam hal ini. Saya akan menjelaskan alasannya.

TypeScript bukan sistem tipe yang dapat diandalkan


Saya pikir ini mungkin masalah utama dengan TypeScript, tapi pertama-tama izinkan saya menentukan apa jenis sistem yang dapat diandalkan dan tidak dapat diandalkan .

Sistem Tipe Kuat


Sistem tipe yang andal memastikan bahwa program Anda tidak berakhir dalam keadaan tidak valid. Misalnya, jika tipe statis dari ekspresi adalah string , ketika dievaluasi pada saat run, Anda dijamin hanya akan mendapatkan string .

Dalam sistem tipe yang andal, Anda tidak akan pernah berada dalam situasi di mana ekspresi tidak cocok dengan tipe yang diharapkan, baik pada waktu kompilasi atau pada saat run time.

Tentu saja, ada berbagai tingkat keandalan, serta berbagai interpretasi keandalan. TypeScript agak dapat diandalkan dan menangkap kesalahan tipe:

// Type 'string' is not assignable to type 'number' const increment = (i: number): number => { return i + "1"; } // Argument of type '"98765432"' is not assignable to parameter of type 'number'. const countdown: number = increment("98765432"); 

Sistem Jenis Tidak Aman


Typescript benar-benar secara terbuka melaporkan bahwa keandalan 100% bukan tujuannya. Bahkan "non-target" nomor 3 pada daftar "non-target" TypeScript dengan jelas menyatakan:
Memiliki sistem tipe yang andal atau "terbukti benar" bukanlah tujuan kami. Alih-alih, kami berusaha untuk mencapai keseimbangan antara akurasi dan kinerja.

Ini berarti bahwa tidak ada jaminan bahwa variabel adalah tipe tertentu pada saat dijalankan. Saya dapat menggambarkan ini dengan contoh yang agak dibuat-buat berikut:

 interface A { x: number; } let a: A = {x: 3} let b: {x: number | string} = a; bx = "unsound"; let x: number = ax; // unsound axtoFixed(0); // WTF is it? 

Kode di atas tidak berfungsi, karena diketahui bahwa kapak adalah angka dari antarmuka A. Sayangnya, setelah beberapa tipuan dengan penugasan kembali, itu berubah menjadi string dan kode ini dikompilasi, tetapi dengan kesalahan saat runtime.

Sayangnya, ungkapan ini dikompilasi tanpa kesalahan:

 axtoFixed(0); 

Keandalan itu bukan tujuan bahasa mungkin salah satu masalah terbesar TypeScript. Saya terus mendapatkan banyak kesalahan runtime error saat runtime yang tidak ditangkap oleh compiler tsc , tetapi kompiler itu akan memperhatikan jika TypeScript memiliki sistem tipe yang kuat. TypeScript sekarang satu kaki di kamp bahasa "dapat diandalkan", dan yang lainnya di "tidak dapat diandalkan." Pendekatan setengah-setengah ini didasarkan pada jenis apa pun , yang akan saya bahas nanti.

Saya frustrasi dengan kenyataan bahwa jumlah tes yang saya tulis tidak berkurang sama sekali dengan transisi ke TypeScript. Ketika saya baru mulai, saya keliru memutuskan bahwa saya dapat mengurangi rutinitas yang berat dalam menulis sejumlah besar unit test.

TypeScript menantang keadaan saat ini dengan berpendapat bahwa menurunkan biaya kognitif saat menggunakan jenis lebih penting daripada keandalan.

Saya mengerti mengapa TypeScript telah memilih jalur seperti itu dan ada pendapat bahwa TypeScript tidak akan begitu populer jika keandalan sistem tipe dijamin 100%. Pendapat ini tidak tahan uji - bahasa Dart dengan cepat mendapatkan popularitas, seiring dengan meluasnya penggunaan Flutter. Dan dikatakan bahwa reliabilitas tipe adalah tujuan Dart.

Ketidakamanan dan berbagai cara yang diberikan oleh TypeScript sebagai "pintu darurat" dari pengetikan yang kuat membuatnya kurang efisien dan, sayangnya, menjadikannya "lebih baik daripada tidak sama sekali" saat ini. Saya akan senang jika TypeScript semakin populer, lebih banyak opsi kompiler tersedia, memungkinkan pengguna berpengalaman untuk mengusahakan keandalan 100%.

TypeScript tidak menjamin semua tipe memeriksa pada saat runtime


Pengecekan tipe saat runtime bukan tujuan dari TypeScript, jadi keinginan saya mungkin tidak akan pernah menjadi kenyataan. Pemeriksaan jenis run-time berguna, misalnya, ketika bekerja dengan data JSON yang dikembalikan dari panggilan API. Adalah mungkin untuk menyingkirkan seluruh kategori kesalahan dan banyak unit test, jika kita bisa mengendalikan proses-proses ini pada level sistem tipe.

Karena kami tidak dapat menjamin apa pun pada saat runtime, ini dapat dengan mudah terjadi:

 const getFullName = async (): string => { const person: AxiosResponse = await api(); //response.name.fullName may result in undefined at runtime return response.name.fullName } 

Ada beberapa perpustakaan pembantu seperti io-ts , yang bagus, tetapi itu mungkin berarti Anda harus menduplikasi model Anda.

Jenis menakutkan opsi apa pun dan ketat


Tipe any berarti "any", dan kompiler memungkinkan operasi atau penugasan variabel apa pun dari tipe ini.

TypeScript bekerja dengan baik untuk hal-hal kecil, tetapi orang-orang cenderung menempatkan jenis apa pun pada apa pun yang membutuhkan waktu lebih dari satu menit. Saya baru-baru ini mengerjakan proyek Angular dan melihat banyak kode seperti ini:

 export class Person { public _id: any; public name: any; public icon: any; 

TypeScript memungkinkan Anda melupakan sistem tipe.

Anda dapat merusak jenis apa pun dengan:

 ("oh my goodness" as any).ToFixed(1); // remember what I said about soundness? 

Opsi ketat mencakup opsi kompiler berikut, yang membuat semuanya lebih dapat diandalkan:

  • --strictNullChecks
  • --noImplicitAny
  • --tidak terapkan Ini
  • --selalu ketat

Ada juga aturan eslint @ typescript-eslint / no-eksplisit-apa pun .

Mendistribusikan apa pun dapat merusak keandalan kode Anda.

Kesimpulan


Saya harus mengulang bahwa saya adalah penggemar TypeScript dan menggunakannya dalam pekerjaan sehari-hari saya, tetapi saya merasa itu tidak sempurna dan hype di sekitarnya tidak sepenuhnya dibenarkan. Airbnb mengklaim TypeScript membantu mencegah 38% kesalahan . Saya sangat skeptis tentang persentase yang dinyatakan secara akurat. TypeScript tidak meningkatkan atau menggabungkan semua praktik kode baik yang ada. Saya masih harus menulis banyak tes. Anda bisa berpendapat bahwa saya menulis lebih banyak kode, jadi saya harus menulis begitu banyak tes. Saya terus mendapatkan banyak kesalahan runtime yang tidak terduga.

TypeScript hanya menawarkan pengecekan tipe dasar, dan fakta bahwa reliabilitas dan pengecekan tipe pada saat runtime bukan tujuannya meninggalkan TypeScript di dunia setengah-setengah, di tengah-tengah antara dunia terbaik dan dunia di mana kita kode sekarang.

TypeScript sangat bagus berkat dukungan baik dari IDE seperti vscode, di mana kami mendapatkan umpan balik visual selama proses pencetakan.


Kesalahan ketikScript dalam vscode

TypeScript juga meningkatkan perubahan refactoring dan pemecahan kode (seperti perubahan dalam tanda tangan metode) yang secara instan diidentifikasi ketika kompiler TypeScript dimulai.
TypeScript menyediakan pemeriksaan jenis yang baik dan jelas lebih baik daripada tidak ada pemeriksaan jenis atau eslint sederhana, tetapi saya merasa bahwa TypeScript bisa jauh lebih baik dan opsi kompiler yang diperlukan dapat menyenangkan mereka yang menginginkan lebih dari bahasa.



Berlangganan pengembang Instagram kami


Source: https://habr.com/ru/post/id485206/


All Articles