BerandaComputers and TechnologyJenis router url yang diperiksa di TypeScript

Jenis router url yang diperiksa di TypeScript

Ini berlaku untuk TypeScript 4.1 dan yang lebih baru.

Router, bagian sentral dalam banyak aplikasi web, terkadang diketik dengan string . Dengan inspirasi dari Dan Vanderkam kiriman Twitter , kita akan memeriksa bagaimana membangun sebuah router berbasis url dimana route adalah tipe diperiksa. Setiap rute akan menjadi pasangan [component, template] di mana komponen adalah fungsi seperti di React, dan template adalah string yang bisa kita cocokkan dengan url. Kami menggunakan TypeScript untuk memastikan bahwa template memperhitungkan semua properti wajib yang diperlukan untuk membuat instance komponen pasangannya.

Langsung ke demo

Mari kita mulai dengan membuat sebuah komponen bernama Halaman:

Berdasarkan PageProps, dua properti diperlukan untuk membuat komponen ini; postId dan commentId, sedangkan searchQuery bersifat opsional. Properti dideklarasikan sebagai string, dan komponen bertanggung jawab untuk mengubahnya menjadi tipe yang sesuai. Url ke komponen bisa jadi https://example.com/posts/10/comments/83 di mana string kueri akan bertindak sebagai rangkaian pasangan nilai kunci untuk properti opsional, seperti https://example.com/posts/10/comments/83?searchQuery=recipe . Mengabaikan properti opsional, karena tidak dapat menyebabkan aplikasi gagal dalam kasus tidak ada, templatnya harus sesuai dengan properti yang diwajibkan oleh Halaman, dan untuk melakukannya, kita membutuhkan template seperti posts /: postId / comments /: commentId di mana variabel diawali dengan titik dua dan dinamai sesuai dengan properti yang mereka cocokkan. Mengekstrak variabel dari template menjadi gabungan dimungkinkan melalui jenis literal template :

Perhatikan bahwa InvalidTemplate memiliki variabel: workerId, tetapi akan mengandung kesalahan. Mendukung prefiks dan postfix untuk variabel, templat perlu diurutkan. Ucapkan template berikut ditentukan, dan pengunjung masuk ke https://example.com/a/B1234

Template Template cocok dengan B1234?
membantu Ya (id=B1234)
tawaran Ya (id=1234)

Menyortir templat dengan titik dua terakhir akan menjadi langkah ke arah yang benar, tetapi itu jauh lebih mudah dengan hanya mengubah template berawalan-B menjadi a / b /: id.

Selanjutnya kita akan mengekstrak kunci yang diperlukan dari PageProps, menggunakan tipe (yang sedikit diubah) oleh Joe Calzaretta dari Stack Overflow .

Mengetahui properti yang diperlukan dan variabel apa yang diambil template, dimungkinkan untuk memvalidasi bahwa template dapat membuat instance dengan benar komponen pasangannya.

Aneh – template memiliki variabel yang tidak mencukupi untuk menginisialisasi Halaman karena tidak memiliki userId, tetapi TypeScript memberi tahu kita bahwa itu valid. Itu karena A memanjang B berarti A adalah himpunan bagian dari B dan itu benar, karena variabel yang diekstrak "postId" | "commentId" adalah subset dari "postId" | "commentId" | "identitas pengguna".

Untuk mengatasinya, kita harus memeriksa bahwa keduanya saling memperluas, mis. dengan kendala A memanjang B, B memanjang A . Jika keduanya merupakan bagian dari satu sama lain, keduanya harus sama. Tetapi menulis yang menyebabkan TypeScript mengeluh tentang kendala melingkar, jadi kami menuju ke Repo Github TypeScript dan salin tipe Equals dari Matt McCutchen.

Dengan Sama dengan , RequiredKeys & ltT> dan Variabel Template , kami memiliki yang diperlukan jenis untuk menentukan rute, atau pasangan komponen dan template.

Coba hapus string meluas U? U: pada kode di atas. TypeScript akan mengeluh tentang pesan kesalahan potensial dalam Template, karena tidak memperluas string. Ini sangat disayangkan kode diperlukan. Mudah-mudahan suatu hari kita bisa melempar kesalahan ke dalam tipe.

Hampir setiap baris yang ditulis sejauh ini dihapus oleh kompilator. Saatnya mengotori tangan kita dan tulis beberapa JavaScript lama yang bagus, ditaburi dengan TypeScript. Sesuatu yang dapat mengubah url menjadi objek, objek yang akan kita berikan ke komponen yang cocok dengan url, dan sesuatu yang dapat melakukan kebalikannya, mengubah objek menjadi url, url benar yang cocok template.

Kita bisa menggunakan banyak tipe mewah di sini, tapi mari kita buat tipe abstraksi aman di atasnya nanti. Pertama kita akan mengintegrasikan dengan Sejarah .

Selanjutnya adalah tautan.

Saatnya menyelesaikan semuanya dan membuat aplikasi demo!

Klik Kompilasi untuk melihat router beraksi.

Bonus: Periksa templat yang tumpang tindih

Tidak bisa mendapatkan pemeriksaan jenis yang cukup? Aku juga tidak bisa! Kami dapat memeriksa templat yang tumpang tindih seperti : postId /: commentId dan : postId /: relatedPostIds . Jika Anda memiliki keduanya template, tidak ditentukan mana yang cocok, karena url mengaksesnya, mis. https://example.com/100/10 akan cocok dengan kedua template. Contoh lainnya adalah template tanpa variabel. Katakanlah Anda memiliki dua komponen dan Anda secara tidak sengaja menentukan template yang sama untuk keduanya, maka tidak akan ditentukan mana yang cocok juga.

Triknya adalah dengan terlebih dahulu mengubah template menjadi string di mana nama variabel diganti nama yang sama setiap saat. Jadi template seperti a /: x /: y diubah menjadi a /: var /: var . Haruskah ada komponen lain dengan template seperti a /: myVar /: myOtherVar , ini juga akan diubah menjadi a /: var /: var , dan sekarang kita tahu mereka tumpang tindih.

Sebelum melanjutkan, kita perlu menyelidiki bagaimana tipe dan array gabungan bekerja.

Sekarang kami memiliki dua kunci di RouteKeys, dan satu di RouteUnion. RouteKeys tidak akan pernah mendapatkannya dikurangi menjadi kunci kurang dari apa yang ada di objek, karena objek tidak memungkinkan kunci duplikat. Jika kita punya cara untuk menghitung berapa banyak tipe yang ada dalam satu tipe serikat, kita bisa membandingkan panjang (RouteUnion) dengan panjang (RouteKeys), dan jika tidak sama, itu berarti bahwa templat telah dikurangi dalam tipe gabungan karena menjadi duplikat, atau dalam istilah lain, template tersebut tumpang tindih dengan template lain.

Sayangnya kami tidak dapat menghitung tipe dalam sebuah serikat pekerja, tetapi dengan bantuan a tipe ajaib , mereka bisa diubah menjadi array, atau tuple, dan yang bisa kita hitung. Saya tidak akan melalui tipe karena saya tidak memahaminya, bagi saya itu adalah kotak hitam tempat Anda memasukkan tipe serikat dan mendapatkan tupel sebagai gantinya.

Dengan tipe sihir yang kami miliki, sisanya mudah. ​​

Gangguan kecil di sini adalah kesalahan digabungkan, jadi satu templat yang tidak valid akan menyebabkan pemeriksa tipe untuk menandai semua rute sebagai tidak valid. Kirimi saya email jika Anda tahu cara menyiasatinya.

Itu dia. Saya harap Anda menikmati artikel ini, dan terima kasih telah membaca.

Read More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments