TypeScript
Type guards и сужение типов
Пользовательские предикаты и проверка неизвестных данных из внешних источников.
Код
interface User { kind: 'user'; username: string }
interface Admin { kind: 'admin'; username: string; permissions: string[] }
type Account = User | Admin;
// Дискриминированное объединение — сужение по полю kind
function describe(account: Account): string {
switch (account.kind) {
case 'admin':
return `${account.username}: ${account.permissions.join(', ')}`;
case 'user':
return account.username;
default:
return assertNever(account); // ошибка компиляции, если добавят вариант
}
}
function assertNever(value: never): never {
throw new Error(`Необработанный вариант: ${JSON.stringify(value)}`);
}
// Предикат для данных из сети (unknown → User)
function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'kind' in value &&
(value as User).kind === 'user' &&
typeof (value as User).username === 'string'
);
}
const raw: unknown = JSON.parse('{"kind":"user","username":"ivan"}');
if (isUser(raw)) console.log(raw.username.toUpperCase());