← Wszystkie zadaniaTypeScript · Senior

Branded types: UserId i OrderId

W kodzie są identyfikatory użytkowników (u_ann) i zamówień (o_42), oba to napisy, więc łatwo je pomylić w argumentach. Zrób z UserId i OrderId różne typy: zwykły napis ani identyfikator innego rodzaju nie mogą być przypisane, ale UserId ma pozostać napisem (toUpperCase, przypisanie do string).

Funkcje userId(value) i orderId(value) sprawdzają format (u_ i litery, cyfry lub _; o_ i cyfry), rzucają Invalid UserId / Invalid OrderId i zwracają wartość z właściwym typem.

Testy (7)

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.

  1. typy
    // @ts-expect-error - a plain string is not a UserId
    const id: UserId = 'u_ann';
  2. typy
    const u = userId('u_ann');
    // @ts-expect-error - a UserId is not an OrderId
    const o: OrderId = u;
  3. typy
    const u = userId('u_ann');
    const s: string = u;
    const upper = u.toUpperCase();
  4. typy
    type _ = Expect<Equal<ReturnType<typeof orderId>, OrderId>>;
  5. expect(userId('u_ann')).toBe('u_ann');
    expect(orderId('o_42')).toBe('o_42');
  6. expect(() => userId('ann')).toThrow('Invalid UserId');
  7. expect(() => orderId('o_abc')).toThrow('Invalid OrderId');
    expect(() => orderId('u_1')).toThrow('Invalid OrderId');