typescript-patterns
Dari discriminated unions, template literal types, sampai satisfies operator — pola TypeScript yang bikin kode lebih aman tanpa over-engineering tipe.
Banyak developer jatuh ke dua ekstrem: terlalu sedikit TypeScript (banyak any) atau terlalu banyak (generic fractal yang gak ada yang ngerti). Post ini bahas sweet spot-nya.
Discriminated Unions
Pattern paling underrated di TypeScript. Intinya: punya union type yang bisa di-bedakan lewat satu field literal.
type Result =
| { status: "success"; data: User }
| { status: "error"; error: string }
| { status: "loading" }
function handle(result: Result) {
switch (result.status) {
case "success": console.log(result.data.name); break
case "error": console.error(result.error); break
}
}Ini dipakai di mana-mana di codebase: ButtonAsButton | ButtonAsLink, variant styles map — eliminasi impossible state tanpa runtime check.
satisfies operator
TS 4.9 bawa satisfies. Bedanya dengan type annotation: infer literal type, tapi tetap validate.
const config = { width: 800, height: 480 } satisfies Record<string, number>
config.width // type: 800 (literal), bukan numberconst assertions
as const bikin TS infer tipe paling narrow — autocomplete perfect tanpa maintain dua source of truth.
Kapan berhenti
Rule of thumb: jangan bikin generic kalau cuma dipakai sekali. Fokus ke model data yang akurat, bukan generic yang reusable tapi gak ada yang reuse.