TypeScript

Type guards и сужение типов

Algonexys · 07.08.2026 · 👁 0

Пользовательские предикаты и проверка неизвестных данных из внешних источников.

Код

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());