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