История вопроса:
TypeScript предназначен для добавления статической типизации к существующим JS-приложениям. Возникает вопрос — как типизировать импорт, если мы подключаем сторонний или свой же модуль, написанный на чистом JavaScript, где типов нет? В этом случае TypeScript использует так называемые declaration files (.d.ts), либо выводит типы автоматически (иногда неправильно).
Проблема:
Если при импорте TypeScript не находит подходящее описание типов, переменная приобретает тип any, что значит — полная потеря типовой безопасности. Это может привести к ошибкам, которые компилятор не заметит, и к багам в рантайме. Часто разработчики забывают явно объявлять типы для импортируемых функций/объектов.
Решение:
Пример кода:
// 1. Явная типизация импорта JS-модуля import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. Импорт из JS-модуля, для которого создан файл myLib.d.ts с export function myFunc(x: number): boolean; import { myFunc } from './myLib'; // 3. Импортируем модуль без типизации и явно описываем тип import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;
Ключевые особенности:
Может ли TypeScript автоматически вывести типы импортируемого JS-модуля без деклараций?
Нет, если файл написан на JavaScript, без деклараций типов TypeScript вынужден предположить any и теряет информацию о типах, кроме тривиальных случаев (export const x = 1;).
Можно ли "расширить" импортированные типы, если появляются новые поля в JS-модуле?
Только если вы обновите декларационный файл (.d.ts). Если типы зафиксированы в .d.ts, TypeScript будет использовать их как "истину", любые новые поля останутся без типизации либо приведут к ошибке.
Безопасно ли импортировать сторонний JS-модуль в TypeScript-проект, если для него нет @types/ и деклараций?
Нет, это резко снижает безопасность — вся работа с импортом оказывается untyped (any), компилятор не выдаст ошибок, даже если модуль недоступен или API изменилось. Работа с такими модулями допустима только как временное решение, с явной типизацией или изоляцией кода.
Разработчик импортирует стороннюю JS-библиотеку без деклараций, уверенно использует API, получая тип any. После обновления библиотеки меняется сигнатура методов, но ошибки не возникают, лишь баги в рантайме.
Плюсы:
Минусы:
Создается декларационный файл .d.ts или добавляется @types/пакет, описание API строго соответствует исходному JS-модулю. Все импортируемые методы типизированы, IDE подсказывает автодополнение, любые несовпадения показывают ошибку компиляции.
Плюсы:
Минусы: