Rumah > hujung hadapan web > tutorial js > Menguasai Jenis Literal Templat TypeScript: Meningkatkan Keselamatan Kod dan Ekspresif

Menguasai Jenis Literal Templat TypeScript: Meningkatkan Keselamatan Kod dan Ekspresif

Patricia Arquette
Lepaskan: 2024-11-22 09:50:11
asal
653 orang telah melayarinya

Mastering TypeScript

Baiklah, mari kita terjun ke dunia yang menarik dalam pengaturcaraan meta masa kompilasi dalam TypeScript menggunakan jenis literal templat. Ciri berkuasa ini membolehkan kami mencipta sihir tahap jenis yang sangat hebat yang boleh menjadikan kod kami lebih selamat dan lebih ekspresif.

Pertama sekali, apakah sebenarnya jenis literal templat? Ia adalah cara untuk memanipulasi dan mencipta jenis baharu berdasarkan literal rentetan. Ia seperti mempunyai bahasa pengaturcaraan mini hanya untuk jenis anda. Agak kemas, kan?

Mari kita mulakan dengan contoh mudah:

type Greeting<T extends string> = `Hello, ${T}!`;
type Result = Greeting<"World">; // "Hello, World!"
Salin selepas log masuk
Salin selepas log masuk

Di sini, kami telah mencipta jenis yang mengambil rentetan dan membungkusnya dengan ucapan. Pengkompil TypeScript memikirkan jenis yang terhasil pada masa penyusunan. Ini hanya mencalarkan permukaan.

Kami boleh menggunakan jenis literal templat untuk mencipta transformasi yang lebih kompleks. Sebagai contoh, katakan kita ingin mencipta jenis yang menukarkan snake_case kepada camelCase:

type SnakeToCamel<S extends string> = S extends `${infer T}_${infer U}`
  ? `${T}${Capitalize<SnakeToCamel<U>>}`
  : S;

type Result = SnakeToCamel<"hello_world_typescript">; // "helloWorldTypescript"
Salin selepas log masuk
Salin selepas log masuk

Jenis ini secara rekursif mengubah rentetan input, menggunakan huruf besar setiap bahagian selepas garis bawah. Kata kunci kesimpulan adalah penting di sini - ia membolehkan kami mengekstrak bahagian rentetan ke dalam pembolehubah jenis baharu.

Tetapi kenapa berhenti di situ? Kami boleh menggunakan teknik ini untuk membina keseluruhan bahasa khusus domain (DSL) dalam sistem jenis kami. Bayangkan mencipta pembina pertanyaan SQL yang selamat jenis:

type Table = "users" | "posts" | "comments";
type Column = "id" | "name" | "email" | "content";

type Select<T extends Table, C extends Column> = `SELECT ${C} FROM ${T}`;
type Where<T extends string> = `WHERE ${T}`;

type Query<T extends Table, C extends Column, W extends string> = 
  `${Select<T, C>} ${Where<W>}`;

type UserQuery = Query<"users", "name" | "email", "id = 1">; 
// "SELECT name, email FROM users WHERE id = 1"
Salin selepas log masuk
Salin selepas log masuk

Persediaan ini memastikan bahawa kami hanya memilih lajur yang sah daripada jadual yang sah, semuanya diperiksa pada masa penyusunan. Tiada lagi ralat masa jalan daripada nama lajur yang salah taip!

Kita boleh mengambil langkah ini lebih jauh dengan melaksanakan pengiraan peringkat jenis yang lebih kompleks. Mari cipta jenis yang boleh melakukan aritmetik asas:

type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type AddDigits<A extends Digit, B extends Digit> = 
  // ... (implementation details omitted for brevity)

type Add<A extends string, B extends string> = 
  // ... (implementation details omitted for brevity)

type Result = Add<"123", "456">; // "579"
Salin selepas log masuk
Salin selepas log masuk

Jenis ini boleh menambah dua nombor yang diwakili sebagai rentetan. Pelaksanaan sebenar agak kompleks dan melibatkan banyak jenis bersyarat dan rekursi, tetapi hasil akhirnya adalah sihir masa kompilasi tulen.

Satu aplikasi praktikal teknik ini adalah dalam mencipta skema pengesahan borang lanjutan. Kami boleh menentukan jenis yang menerangkan bentuk borang kami dan menggunakannya untuk menjana peraturan pengesahan:

type Form = {
  name: string;
  email: string;
  age: number;
};

type ValidationRule<T> = T extends string
  ? "isString"
  : T extends number
  ? "isNumber"
  : never;

type ValidationSchema<T> = {
  [K in keyof T]: ValidationRule<T[K]>;
};

type FormValidation = ValidationSchema<Form>;
// { name: "isString", email: "isString", age: "isNumber" }
Salin selepas log masuk

Skema ini kemudiannya boleh digunakan untuk menjana kod pengesahan masa jalan, memastikan logik pengesahan kami sentiasa sepadan dengan definisi jenis kami.

Jenis literal templat juga membolehkan kami mencipta API yang lebih fleksibel. Kita boleh menggunakannya untuk melaksanakan rantaian kaedah dengan inferens jenis yang betul:

type Chainable<T> = {
  set: <K extends string, V>(key: K, value: V) => Chainable<T & { [P in K]: V }>;
  get: () => T;
};

declare function createChainable<T>(): Chainable<T>;

const result = createChainable()
  .set("foo", 123)
  .set("bar", "hello")
  .get();

// result type: { foo: number, bar: string }
Salin selepas log masuk

Corak ini membolehkan kami membina objek langkah demi langkah, dengan sistem jenis menjejaki sifat terkumpul pada setiap langkah.

Salah satu aspek yang paling berkuasa dalam pengaturcaraan meta masa kompilasi ialah keupayaan untuk menjana jenis baharu berdasarkan yang sedia ada. Kita boleh menggunakan ini untuk mencipta jenis utiliti yang mengubah jenis lain dengan cara yang berguna. Sebagai contoh, mari buat jenis yang menjadikan semua sifat objek sebagai pilihan, tetapi hanya pada tahap pertama:

type Greeting<T extends string> = `Hello, ${T}!`;
type Result = Greeting<"World">; // "Hello, World!"
Salin selepas log masuk
Salin selepas log masuk

Jenis ini menjadikan sifat peringkat teratas sebagai pilihan, tetapi membiarkan objek bersarang tidak berubah. Ia adalah versi yang lebih bernuansa bagi jenis Separa terbina dalam TypeScript.

Kami juga boleh menggunakan jenis literal templat untuk mencipta mesej ralat yang lebih ekspresif. Daripada mendapat ralat jenis samar, kami boleh membimbing pembangun kepada masalah yang tepat:

type SnakeToCamel<S extends string> = S extends `${infer T}_${infer U}`
  ? `${T}${Capitalize<SnakeToCamel<U>>}`
  : S;

type Result = SnakeToCamel<"hello_world_typescript">; // "helloWorldTypescript"
Salin selepas log masuk
Salin selepas log masuk

Teknik ini amat berguna dalam pembangunan perpustakaan, yang memberikan maklum balas yang jelas kepada pengguna adalah penting.

Satu lagi aplikasi menarik ialah dalam mencipta pemancar acara selamat jenis. Kami boleh menggunakan jenis literal templat untuk memastikan nama acara dan muatan sepadannya dipadankan dengan betul:

type Table = "users" | "posts" | "comments";
type Column = "id" | "name" | "email" | "content";

type Select<T extends Table, C extends Column> = `SELECT ${C} FROM ${T}`;
type Where<T extends string> = `WHERE ${T}`;

type Query<T extends Table, C extends Column, W extends string> = 
  `${Select<T, C>} ${Where<W>}`;

type UserQuery = Query<"users", "name" | "email", "id = 1">; 
// "SELECT name, email FROM users WHERE id = 1"
Salin selepas log masuk
Salin selepas log masuk

Persediaan ini memastikan kami sentiasa mengeluarkan dan mendengar acara dengan jenis muatan yang betul.

Jenis literal templat juga boleh digunakan untuk melaksanakan mesin keadaan peringkat jenis. Ini boleh menjadi sangat berguna untuk memodelkan aliran kerja atau protokol yang kompleks:

type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type AddDigits<A extends Digit, B extends Digit> = 
  // ... (implementation details omitted for brevity)

type Add<A extends string, B extends string> = 
  // ... (implementation details omitted for brevity)

type Result = Add<"123", "456">; // "579"
Salin selepas log masuk
Salin selepas log masuk

Mesin keadaan ini selamat jenis sepenuhnya - ia tidak akan membenarkan peralihan yang tidak sah dan akan menjejaki keadaan semasa dengan tepat.

Kesimpulannya, pengaturcaraan meta masa kompilasi dengan jenis literal templat dalam TypeScript membuka dunia kemungkinan. Ia membolehkan kami mencipta kod yang lebih ekspresif, selamat jenis dan pendokumentasian sendiri. Kami boleh menangkap ralat lebih awal, memberikan pengalaman pembangun yang lebih baik, dan juga menjana kod berdasarkan jenis. Walaupun teknik ini boleh menjadi rumit, ia menawarkan alat yang berkuasa untuk membina sistem yang teguh dan fleksibel. Seperti mana-mana ciri lanjutan, adalah penting untuk menggunakannya dengan bijak - kadangkala penyelesaian yang lebih mudah lebih boleh diselenggara. Tetapi apabila digunakan dengan baik, pengaturcaraan meta masa kompilasi boleh meningkatkan kualiti dan kebolehpercayaan kod TypeScript kami dengan ketara.


Ciptaan Kami

Pastikan anda melihat ciptaan kami:

Pusat Pelabur | Hidup Pintar | Epos & Gema | Misteri Membingungkan | Hindutva | Pembangunan Elit | Sekolah JS


Kami berada di Medium

Tech Koala Insights | Dunia Epok & Gema | Medium Pusat Pelabur | Medium Misteri Membingungkan | Sains & Zaman Sederhana | Hindutva Moden

Atas ialah kandungan terperinci Menguasai Jenis Literal Templat TypeScript: Meningkatkan Keselamatan Kod dan Ekspresif. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan