Result<T, E>: błędy bez wyjątków
Typ Result<T, E> to albo sukces { ok: true, value }, albo błąd { ok: false, error }. Napisz do niego funkcje pomocnicze z dokładnymi typami.
ok(value) i err(error) tworzą wynik, mapResult(result, fn) przekształca wartość sukcesu i przepuszcza błąd bez zmian (nie wywołując fn), a unwrapOr(result, fallback) zwraca wartość albo wartość zapasową. Typ błędu ma przechodzić do wyniku mapResult.
Ctrl+Enter uruchamia testy. Tab robi wcięcie; aby wyjść z edytora klawiaturą, naciśnij Esc, a potem Tab. Kod zapisuje się w tej przeglądarce.
Testy (8)
Testy typów sprawdza kompilator TypeScriptu w trybie strict. Expect<Equal<A, B>> przechodzi, gdy typy są dokładnie takie same, a // @ts-expect-error, gdy następna linia się nie kompiluje. Pierwsze uruchomienie pobiera kompilator, więc trwa kilka sekund.
- typy
const r = ok(42); type _ = Expect<Equal<typeof r, Result<number, never>>>;
- typy
const e = err('not found'); type _ = Expect<Equal<typeof e, Result<never, string>>>;
- typy
const r = {} as Result<number, string>; const m = mapResult(r, (n) => String(n)); type _ = Expect<Equal<typeof m, Result<string, string>>>;
- typy
const r = {} as Result<number, string>; const v = unwrapOr(r, 0); type _ = Expect<Equal<typeof v, number>>;
expect(ok(1)).toEqual({ ok: true, value: 1 }); expect(err('x')).toEqual({ ok: false, error: 'x' });
expect(mapResult(ok(2), (n) => n * 10)).toEqual({ ok: true, value: 20 });
const f = fn((n) => n * 10); const failure = err('bad'); expect(mapResult(failure, f)).toEqual({ ok: false, error: 'bad' }); expect(f).toHaveBeenCalledTimes(0);
expect(unwrapOr(ok(5), 0)).toBe(5); expect(unwrapOr(err('bad'), 0)).toBe(0);