Программирование с ИИ
ENRU
9.3

Что добавляет TypeScript

тот же JavaScript, но с проверкой

Что это

TypeScript — это JavaScript плюс описания типов. Браузер его не исполняет: перед запуском типы стираются, и остаётся обычный JavaScript. Вся польза происходит до запуска, в момент проверки.

Для работы с ИИ это принципиально. Вернись к статье 6.3: там mypy поймал забытую проверку на null в Python до запуска. TypeScript делает то же самое для фронтенда — и делает это строже, потому что здесь типы не опциональная добавка, а основной режим работы.

Как выглядит в коде

interface City {
  name: string;
  temp: number | null;
  tags?: string[];
}

function report(c: City): string {
  if (c.temp === null) return `${c.name}: нет данных`;
  return `${c.name}: ${c.temp > 0 ? "+" : ""}${c.temp}°`;
}

const cities: City[] = [
  { name: "Oslo", temp: 4 },
  { name: "Tromsø", temp: null },
  { name: "Bergen", temp: -2, tags: ["дождь"] },
];

cities.forEach(c => console.log(report(c)));
измерено
tsc: ошибок нет
Oslo: +4°
Tromsø: нет данных
Bergen: -2°

Как это читать

interface City { ... } — описание формы объекта. Не класс, не код: после компиляции от него ничего не останется.

temp: number | null — union, «или одно, или другое». Самая полезная запись в TypeScript: она прямо говорит, что значения может не быть, и компилятор заставит это проверить.

tags?: string[] — необязательное поле. Его тип на самом деле string[] | undefined.

function report(c: City): string — принимает City, возвращает строку. То же, что сигнатура в Python (статья 6.5), и работает так же: заменяет абзац объяснений.

Что происходит без проверки на null

Уберём if и попросим компилятор проверить:

function report(c: City): string {
  return `${c.name}: ${c.temp.toFixed(1)}°`;
}
измерено
error TS18047: 'c.temp' is possibly 'null'.

Код не скомпилируется. Не упадёт у пользователя, не пройдёт мимо тестов — просто не соберётся, пока проверку не добавишь.

Та же ошибка в Python выглядела как Item "None" of "str | None" has no attribute "upper", в JavaScript без типов — как Cannot read properties of null уже во время работы (статья 8.4). Три языка, один класс ошибки, и только здесь он пойман до запуска.

strict — не опция, а смысл

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

Без strict проверка на null отключена, и TypeScript превращается в украшение. Включать обязательно.

noUncheckedIndexedAccess — вторая по полезности настройка. С ней обращение по индексу даёт T | undefined, потому что элемента может не быть:

const cities = ["Oslo", "Bergen"];
const first: string = cities[5];
измерено
error TS2322: Type 'string | undefined' is not assignable to type 'string'.

Компилятор напоминает о том, о чём забывают все: индекс может выйти за границы.

Как запускать

npx tsc --noEmit        # только проверить, ничего не собирать
npx tsx app.ts          # запустить напрямую

--noEmit — то, что нужно чаще всего: проверка без сборки, аналог mypy --strict.

Как сказать ИИ

Запрос
Переведи этот модуль на TypeScript: интерфейсы для данных,
типы у всех функций. tsc --noEmit со strict должен проходить.
Логику не меняй.
Запрос
В tsconfig включи strict и noUncheckedIndexedAccess.
Исправь ошибки, которые появятся, не отключая проверки
и без as any.

Вторая фраза существенная: самый простой способ «исправить» ошибку типов — это её заглушить, и ИИ к этому склонен (статья 9.6).

Запрос
Опиши типы для ответа этого API: вот пример JSON.
Поля, которых может не быть, пометь как необязательные
или | null — честно, а не «чтобы компилировалось».

На что смотреть

strict: false или его отсутствие. Проверка на null выключена, и главная польза потеряна.

any в типах. Отключает проверку для этого места полностью.

as для успокоения компилятора. Про это — отдельно в статье 9.5.

Типы написаны, но tsc не запускался. То же, что аннотации без mypy: украшение, которое разошлось с кодом.

Файлы .js вперемешку с .ts. Переход на полпути: в .js проверок нет, и ошибки прячутся там.

Шпаргалка

  • TypeScript — это JavaScript плюс типы; при запуске типы стираются.

  • interface описывает форму, | — union, ? — необязательное поле.

  • number | null заставляет проверить пустоту — код иначе не соберётся.

  • strict: true обязателен, иначе проверки на null нет.

  • noUncheckedIndexedAccess — обращение по индексу даёт | undefined.

  • npx tsc --noEmit — проверка без сборки, аналог mypy --strict.