Branded Types: UserId und OrderId
Der Code hat Nutzer-IDs (u_ann) und Bestell-IDs (o_42), beides Strings, sie lassen sich in Argumenten also leicht verwechseln. Mach UserId und OrderId zu unterschiedlichen Typen: ein einfacher String oder die andere Art ID darf nicht zuweisbar sein, aber eine UserId soll weiter ein String sein (toUpperCase, Zuweisung an string).
Die Funktionen userId(value) und orderId(value) prüfen das Format (u_ gefolgt von Buchstaben, Ziffern oder _; o_ gefolgt von Ziffern), werfen Invalid UserId / Invalid OrderId und liefern den Wert mit dem richtigen Typ.
Strg+Enter führt die Tests aus. Tab rückt ein; um den Editor per Tastatur zu verlassen, drücke Esc und dann Tab. Der Code wird in diesem Browser gespeichert.
Tests (7)
Typtests prüft der TypeScript-Compiler im strict-Modus. Expect<Equal<A, B>> besteht, wenn die Typen exakt gleich sind, und // @ts-expect-error, wenn die nächste Zeile nicht kompiliert. Der erste Start lädt den Compiler und dauert daher ein paar Sekunden.
- Typen
// @ts-expect-error - a plain string is not a UserId const id: UserId = 'u_ann';
- Typen
const u = userId('u_ann'); // @ts-expect-error - a UserId is not an OrderId const o: OrderId = u;
- Typen
const u = userId('u_ann'); const s: string = u; const upper = u.toUpperCase();
- Typen
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');