Discriminated union nedir? Bir API isteğinin loading/error/success durumunu nasıl modellersiniz?
Cevap
Discriminated union; her üyesinde ortak bir literal etiket alanı (ör. status) bulunan union tipidir. TypeScript bu alanı kontrol ettiğinizde tipi otomatik daraltır ve imkânsız durumları tip seviyesinde engeller.
Kötü model
type State = { loading: boolean; error?: string; data?: User[] };
// loading: true ve data aynı anda dolu olabilir mi? Tip izin veriyor.İyi model
type FetchState<T> =
| { status: "idle" }
| { status: "loading" }
| { status: "error"; error: string }
| { status: "success"; data: T };
function render(state: FetchState<User[]>) {
switch (state.status) {
case "loading":
return "Yükleniyor...";
case "error":
return `Hata: ${state.error}`; // error burada kesin string
case "success":
return state.data.length + " kullanıcı"; // data burada erişilebilir
case "idle":
return null;
default:
return assertNever(state);
}
}
function assertNever(x: never): never {
throw new Error("Beklenmeyen durum: " + JSON.stringify(x));
}Exhaustiveness check
Yarın union'a { status: "refreshing" } eklendiğinde default dalındaki state artık never olmaz ve derleme hatası alırsınız. Bu sayede yeni durumu ele almayı unutan her yer derleyici tarafından bulunur.
Nerede kullanılır?
- Reducer action'ları (
{ type: "add" } | { type: "remove"; id }). - Bileşen props varyantları:
{ variant: "link"; href: string } | { variant: "button"; onClick: () => void }. - "Make impossible states impossible" ilkesinin TypeScript karşılığıdır.
İlgili TypeScript soruları
- any, unknown ve never tipleri arasındaki fark nedir?
- Generic (jenerik) tipler nedir? Bir örnekle açıklayın.
- interface ile type alias arasındaki farklar nelerdir?
- TypeScript nedir, JavaScript'e göre avantajları nelerdir?
- tsconfig.json'daki strict modu neleri açar, neden önemlidir?
- TypeScript'te enum ile union literal tip arasında hangisini tercih edersiniz?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.