← Усі задачіTypeScript · Middle

Result<T, E>: помилки без винятків

Тип Result<T, E> описує або успіх { ok: true, value }, або помилку { ok: false, error }. Напишіть до нього помічники з точними типами.

ok(value) і err(error) створюють результат, mapResult(result, fn) перетворює значення успіху й пропускає помилку без змін (не викликаючи fn), unwrapOr(result, fallback) повертає значення або запасний варіант. Тип помилки має доходити до результату mapResult.

Тести (8)

Тести типів перевіряє компілятор TypeScript у режимі strict. Expect<Equal<A, B>> проходить, коли типи збігаються точно, а // @ts-expect-error - коли наступний рядок не компілюється. Перший запуск завантажує компілятор, тож триває кілька секунд.

  1. типи
    const r = ok(42);
    type _ = Expect<Equal<typeof r, Result<number, never>>>;
  2. типи
    const e = err('not found');
    type _ = Expect<Equal<typeof e, Result<never, string>>>;
  3. типи
    const r = {} as Result<number, string>;
    const m = mapResult(r, (n) => String(n));
    type _ = Expect<Equal<typeof m, Result<string, string>>>;
  4. типи
    const r = {} as Result<number, string>;
    const v = unwrapOr(r, 0);
    type _ = Expect<Equal<typeof v, number>>;
  5. expect(ok(1)).toEqual({ ok: true, value: 1 });
    expect(err('x')).toEqual({ ok: false, error: 'x' });
  6. expect(mapResult(ok(2), (n) => n * 10)).toEqual({ ok: true, value: 20 });
  7. const f = fn((n) => n * 10);
    const failure = err('bad');
    expect(mapResult(failure, f)).toEqual({ ok: false, error: 'bad' });
    expect(f).toHaveBeenCalledTimes(0);
  8. expect(unwrapOr(ok(5), 0)).toBe(5);
    expect(unwrapOr(err('bad'), 0)).toBe(0);