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

Де система типів TypeScript навмисно ненадійна і як закрити ці діри?

TypeScript свідомо не є повністю надійним (sound): заради зручності й сумісності з JavaScript він пропускає деякі програми, що впадуть під час виконання. Важливо знати, де саме.

1. Доступ за індексом:

const items: string[] = [];
const first: string = items[0];   // компілюється, хоча first - undefined
first.toUpperCase();              // падіння

Закриває: "noUncheckedIndexedAccess": true - тоді items[0] має тип string | undefined. Те саме для об'єктів з індексною сигнатурою (Record<string, T>).

2. Коваріантність змінних масивів:

const dogs: Dog[] = [];
const animals: Animal[] = dogs;   // дозволено
animals.push(new Cat());          // тепер у масиві dogs - кіт

Закриває: приймати readonly Animal[] у функціях, що не змінюють масив.

3. Біваріантність параметрів методів:

interface Handler {
  handle(event: Event): void;    // синтаксис методу - біваріантний
}
const h: Handler = { handle(e: MouseEvent) { e.clientX; } };   // дозволено

strictFunctionTypes (частина strict) перевіряє параметри контраваріантно, але лише для властивостей-функцій (handle: (e: Event) => void), а не для синтаксису методів. Тому для колбеків у власних інтерфейсах краще синтаксис властивості.

4. any - вимикає перевірку для всього, до чого торкається, і «заражає» вирази. Закриває: unknown для невідомих даних, правила @typescript-eslint/no-unsafe-*, noImplicitAny.

5. Твердження типу as і ! - компілятор вірить розробнику.

6. Зовнішні дані - відповідь API типізована так, як ви написали, а не так, як прийшло. Закриває лише перевірка під час виконання (Zod, Valibot).

7. Інші місця: опціональні властивості й undefined (закриває exactOptionalPropertyTypes), мутація після звуження в замиканні, некоректні .d.ts бібліотек.

Практичний набір налаштувань для надійності:

{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true
  }
}

З TypeScript 6 strict увімкнено за замовчуванням, але noUncheckedIndexedAccess і exactOptionalPropertyTypes - ні, їх варто додати явно в нових проєктах.

Докладніше в документації: Сумісність типів: про надійність

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