Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим твердження типу as відрізняється від перевірки і коли as виправданий?

as каже компілятору: «повір мені, тут такий тип». Під час виконання нічого не відбувається - ні перевірки, ні перетворення. Якщо розробник помилився, TypeScript мовчить, а помилка вилізе пізніше.

const user = (await response.json()) as User;   // жодної перевірки
const input = document.querySelector('#email') as HTMLInputElement;   // а якщо це <div> чи null?

Перевірка (звуження чи схема) доводить тип під час виконання:

const el = document.querySelector('#email');
if (!(el instanceof HTMLInputElement)) throw new Error('Поле email не знайдено');
el.value;   // тепер справді HTMLInputElement

const user = UserSchema.parse(await response.json());

as не дозволяє будь-яке перетворення: 'text' as number - помилка, бо типи не перетинаються. Обхід через as unknown as number компілюється - і це майже завжди ознака проблеми в коді.

Споріднені конструкції з тими самими ризиками:

  • ! (non-null assertion): user!.name - «тут точно не null»;
  • any - вимикає перевірку зовсім.

Коли as виправданий:

  • TypeScript знає менше за вас, і це можна обґрунтувати: після власної перевірки, яку компілятор не розуміє, або в коді, що працює з DOM, де ви контролюєте розмітку;
  • as const - зовсім інша річ: не обхід перевірки, а звуження до літеральних типів (['draft', 'published'] as const дає кортеж рядкових літералів). Це безпечно й корисно;
  • тести - часткові фіктивні об'єкти ({ id: 1 } as User);
  • межі зі сторонніми бібліотеками з неточними типами - з коментарем, чому.

Кращі альтернативи as:

  • satisfies - перевірити, що значення відповідає типу, не втрачаючи точного виведеного типу:
const routes = {
  home: '/',
  jobs: '/jobs',
} satisfies Record<string, string>;
// routes.home - літерал '/', а друкарська помилка в ключах типу Record<'home'|'jobs', string> була б помічена
  • функції-перевірки типів (value is User) і схеми;
  • анотація змінної (const x: User = {...}) - вона перевіряє зайві й відсутні поля, а as - ні.

Правило лінтера @typescript-eslint/consistent-type-assertions і заборона as unknown as допомагають тримати кількість тверджень під контролем.

Докладніше в документації: Твердження типу

Схожі питання