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

Чим небезпечне приведення типу через as і чим його замінити?

value as T - твердження типу: розробник каже компілятору «вважай це значення типом T». Нічого не перетворюється й не перевіряється під час виконання.

const user = (await response.json()) as User;
user.email.toLowerCase();   // впаде, якщо API повернув { error: '...' }

Компілятор довіряє, а реальні дані можуть бути іншими. Помилка переноситься з місця, де дані прийшли, у випадкове місце далі в коді.

Що as дозволяє, а що ні:

  • звужувати й розширювати в межах сумісних типів (unknown → User, HTMLElement → HTMLInputElement);
  • приведення між несумісними типами ('текст' as number) - помилка компіляції. Але подвійне as unknown as T обходить і це - верна ознака, що щось не так.

Альтернативи:

1. Перевірка під час виконання для зовнішніх даних (API, localStorage, форми):

import { z } from 'zod';

const UserSchema = z.object({ id: z.number(), email: z.email() });
type User = z.infer<typeof UserSchema>;

const user = UserSchema.parse(await response.json());   // кидає помилку, якщо дані не ті

2. Користувацький type guard:

function isUser(value: unknown): value is User {
  return typeof value === 'object' && value !== null && 'email' in value;
}

3. Звуження вбудованими перевірками: instanceof, typeof, in, перевірка поля-дискримінатора.

4. Типізоване API замість приведення: document.querySelector<HTMLInputElement>('input[name=email]') замість as HTMLInputElement; генерік у useState<User | null>(null).

5. satisfies для об'єктів-літералів - перевірка форми без втрати точного типу.

Коли as допустимий:

  • as const - не приведення, а звуження до літеральних типів;
  • тести й моки ({} as Partial<Service> as Service) - з розумінням ризику;
  • місця, де ви знаєте більше за компілятор і це очевидно з контексту (наприклад, після власної перевірки, яку TypeScript не розпізнав).

Правило лінтера @typescript-eslint/consistent-type-assertions дає змогу заборонити as для об'єктних літералів і змусити використовувати анотації чи satisfies.

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

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