Помічник assertNever - замість того, щоб у кожному switch повторювати присвоєння never:
export function assertNever(value: never, message = 'Неочікуване значення'): never {
throw new Error(`${message}: ${JSON.stringify(value)}`);
}
type PaymentMethod =
| { type: 'card'; last4: string }
| { type: 'bank'; iban: string }
| { type: 'cash' };
function label(method: PaymentMethod): string {
switch (method.type) {
case 'card': return `Картка •${method.last4}`;
case 'bank': return `Рахунок ${method.iban}`;
case 'cash': return 'Готівка';
default: return assertNever(method);
}
}
Додали { type: 'crypto' } - компілятор вказує на assertNever(method): аргумент більше не never. А під час виконання (дані прийшли з API в обхід типів) - зрозумілий виняток замість тихого undefined.
Без switch - через об'єкт-мапу з повним набором ключів:
const icons = {
card: 'credit-card',
bank: 'building-columns',
cash: 'money-bill',
} satisfies Record<PaymentMethod['type'], string>;
Новий варіант у типі - помилка, що в мапі бракує ключа.
switch (true) зі звуженням (TypeScript 5.3+). Для умов, які не зводяться до одного поля:
function describe(value: string | number | Date | null): string {
switch (true) {
case value === null:
return '-';
case typeof value === 'string':
return value.trim(); // value: string
case typeof value === 'number':
return value.toFixed(2); // value: number
case value instanceof Date:
return value.toISOString(); // value: Date
default:
return assertNever(value);
}
}
Кожна гілка case звужує тип так само, як if. Це читабельніша альтернатива довгому ланцюжку if/else if.
Помічник match у функціональному стилі - типізований об'єкт обробників:
function match<T extends { type: string }, R>(
value: T,
handlers: { [K in T['type']]: (v: Extract<T, { type: K }>) => R },
): R {
return (handlers as any)[value.type](value);
}
match(method, {
card: (m) => m.last4,
bank: (m) => m.iban,
cash: () => 'готівка',
}); // пропущений обробник - помилка компіляції
Для складних випадків є бібліотека ts-pattern з повноцінним зіставленням зразків і перевіркою вичерпності.