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 - ні, їх варто додати явно в нових проєктах.