Ang TypeScript ay naging industry standard para sa large-scale na web development. Habang alam ng karamihan ng mga developer ang mga pangunahing kaalaman tungkol sa interfaces at types, ang tunay na kapangyarihan ay nasa advanced type system nito. Narito ang 5 pattern na magtatangi sa iyo bilang isang senior engineer.
1. Generic Constraints
Ang Generics ay makapangyarihan, ngunit minsan kailangan mong limitahan kung ano ang maaaring ipasa. Ang extends ang kakampi mo dito.
interface HasId { id: string; } function getById<T extends HasId>(list: T[], id: string): T | undefined { return list.find((item) => item.id === id); }
Sa pamamagitan ng pagtiyak na ang T ay nag-eextend ng HasId, ginagarantiya natin na ligtas ang pag-access sa .id sa loob ng function.
2. Conditional Types
Ang Conditional Types ay nagbibigay-daan sa iyo na lumikha ng mga non-uniform na type mapping. Ang syntax ay katulad ng ternary operator sa JavaScript.
type IsString<T> = T extends string ? true : false; type A = IsString<string>; // true type B = IsString<number>; // false
Isang praktikal na gamit ay ang pag-filter ng mga type mula sa isang union:
type Diff<T, U> = T extends U ? never : T; type NonNullable<T> = Diff<T, null | undefined>;
3. Mapped Types
Ang Mapped Types ay nagbibigay-daan sa iyo na lumikha ng mga bagong type batay sa mga luma sa pamamagitan ng pag-transform ng mga property.
type ReadOnly<T> = { readonly [P in keyof T]: T[P]; }; interface User { name: string; age: number; } type ReadOnlyUser = ReadOnly<User>;
Maaari ka ring magdagdag o mag-alis ng mga modifier:
type Mutable<T> = { -readonly [P in keyof T]: T[P]; };
4. Template Literal Types
Ipinakilala sa TypeScript 4.1, pinapayagan ka nitong manipulahin ang mga string type nang direkta.
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"
Ito ay napaka-kapaki-pakinabang para sa pag-type ng mga string na sumusunod sa isang partikular na pattern, tulad ng CSS classes o event names.
5. Ang infer Keyword
Ang infer keyword sa loob ng conditional types ay nagbibigay-daan sa iyo na i-extract ang mga type mula sa ibang mga type.
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; function check(): boolean { return true; } type CheckReturn = ReturnType<typeof check>; // boolean
Dito, hinihiling natin sa TypeScript na "i-infer" ang return type na R ng isang function at ibalik ito.
Kongklusyon
Ang pag-master ng mga pattern na ito ay nagbibigay-daan sa iyo na magsulat ng mga library at utility na matibay at nagbibigay ng mahusay na developer experience (DX). Ang layunin ng advanced TypeScript ay hindi pagiging kumplikado para sa kapakanan ng pagiging kumplikado, kundi kaligtasan at kakayahang mag-express.