Wzorce
Jak sprawić, by dane sukcesu były dostępne tylko w gałęzi sukcesu, a błędy tylko w gałęzi porażki?
Nadaj każdemu wariantowi jedno wspólne pole literalne. Jego sprawdzenie zawęża cały obiekt, nie tylko pole.
Przepis
type Result<T> = | { status: 'success'; data: T } | { status: 'failure'; error: Error } function unwrap<T>(result: Result<T>): T { if (result.status === 'success') { return result.data } throw result.error }
Build to kompiluje i sprawdza każdy wynik poniżej.
Jak to działa
- 01
status: 'success'Literalny dyskryminator jednoznacznie identyfikuje ten składnik.
- 02
if (result.status === 'success')Analiza przepływu zna teraz każdą inną właściwość wybranego wariantu.
Co dostajesz
Result<number>['status']
→"success" | "failure"Extract<Result<number>, { status: 'success' }>
→{ status: "success"; data: number; }ReturnType<typeof unwrap<string>>
→string
Gdzie to zawodzi
Opcjonalne pola w jednym szerokim obiekcie nie tworzą tej samej korelacji. `status: "success" | "failure"` obok opcjonalnych `data` i `error` nadal przepuszcza niemożliwe kombinacje.
Wniosek
Używaj unii pełnych stanów, nie jednego obiektu pełnego opcjonalnych fragmentów stanu.
