TypeScript telah menjadi standar industri untuk pengembangan web berskala besar. Meskipun sebagian besar pengembang mengetahui dasar-dasar interface dan type, kekuatan sebenarnya terletak pada sistem tipe tingkat lanjutnya. Berikut adalah 5 pola yang akan membedakan Anda sebagai insinyur senior.
1. Generic Constraints
Generics sangat powerful, tetapi terkadang Anda perlu membatasi apa yang bisa dimasukkan. extends adalah teman Anda di sini.
interface HasId { id: string; } function getById<T extends HasId>(list: T[], id: string): T | undefined { return list.find((item) => item.id === id); }
Dengan memastikan T meng-extend HasId, kita menjamin bahwa mengakses .id di dalam fungsi adalah aman.
2. Conditional Types
Conditional types memungkinkan Anda membuat pemetaan tipe yang tidak seragam. Sintaksnya mirip dengan operator ternary di JavaScript.
type IsString<T> = T extends string ? true : false; type A = IsString<string>; // true type B = IsString<number>; // false
Kasus penggunaan praktis adalah memfilter tipe dari union:
type Diff<T, U> = T extends U ? never : T; type NonNullable<T> = Diff<T, null | undefined>;
3. Mapped Types
Mapped types memungkinkan Anda membuat tipe baru berdasarkan tipe yang sudah ada dengan mentransformasi propertinya.
type ReadOnly<T> = { readonly [P in keyof T]: T[P]; }; interface User { name: string; age: number; } type ReadOnlyUser = ReadOnly<User>;
Anda bahkan bisa menambah atau menghapus modifier:
type Mutable<T> = { -readonly [P in keyof T]: T[P]; };
4. Template Literal Types
Diperkenalkan di TypeScript 4.1, fitur ini memungkinkan Anda memanipulasi tipe string secara langsung.
type World = 'world'; type Greeting = `hello ${World}`; // "hello world" type Color = 'red' | 'blue'; type Quantity = 'light' | 'dark'; type Palette = `${Quantity}-${Color}`; // "light-red" | "light-blue" | "dark-red" | "dark-blue"
Ini sangat berguna untuk mengetik string yang mengikuti pola tertentu, seperti kelas CSS atau nama event.
5. Kata Kunci infer
Kata kunci infer dalam conditional types memungkinkan Anda mengekstrak tipe dari tipe lain.
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; function check(): boolean { return true; } type CheckReturn = ReturnType<typeof check>; // boolean
Di sini, kita meminta TypeScript untuk "menyimpulkan" tipe kembalian R dari sebuah fungsi dan mengembalikannya.
Kesimpulan
Menguasai pola-pola ini memungkinkan Anda menulis library dan utilitas yang kokoh dan memberikan pengalaman pengembang (DX) yang sangat baik. Tujuan TypeScript tingkat lanjut bukanlah kompleksitas demi kompleksitas, melainkan keamanan dan ekspresivitas.