Перейти к содержанию

title: Модули: TypeScript description: Встроенная поддержка TypeScript в Node.js — снятие типов, ограничения и полная поддержка через сторонние пакеты


Модули: TypeScript

latest

История
Версия Изменения
REPLACEME Удален флаг --experimental-transform-types.
v25.2.0, v24.12.0 Удаление типов теперь стабильно.
v24.3.0, v22.18.0 Удаление типов больше не выдает экспериментальное предупреждение.
v23.6.0, v22.18.0 Удаление типов включено по умолчанию.
v22.7.0 Добавлен флаг --experimental-transform-types.

Стабильность: 2 – Стабильная

API является удовлетворительным. Совместимость с NPM имеет высший приоритет и не будет нарушена кроме случаев явной необходимости.

Включение

Поддержку TypeScript во время выполнения в Node.js можно включить двумя способами:

  1. Для полной поддержки всего синтаксиса и возможностей TypeScript, включая любую версию TypeScript, используйте сторонний пакет.

  2. Для облегчённого режима можно пользоваться встроенной поддержкой снятия типов.

Полная поддержка TypeScript

Чтобы использовать TypeScript со всеми возможностями, включая tsconfig.json, можно подключить сторонний пакет. Ниже в качестве примера используется [tsx][], но доступны и другие похожие библиотеки.

  1. Установите пакет как dev-зависимость тем менеджером пакетов, которым пользуетесь. Например, с npm:

    1
    npm install --save-dev tsx
    
  2. Запуск TypeScript-кода:

    1
    npx tsx your-file.ts
    

    Либо через node:

    1
    node --import=tsx your-file.ts
    

Снятие типов

Добавлено в: v22.6.0

История
Версия Изменения
v25.2.0, v24.12.0 Удаление типов теперь стабильно.

По умолчанию Node.js выполняет файлы TypeScript, содержащие только стираемый синтаксис TypeScript. Синтаксис TypeScript заменяется пробельными символами, проверка типов не выполняется. Чтобы отключить это поведение, используйте флаг [--no-strip-types][].

Node.js не читает tsconfig.json, поэтому возможности, зависящие от настроек в tsconfig.json (например paths или транспиляция нового JS в старый стандарт), намеренно не поддерживаются. Для полной поддержки TypeScript см. раздел Полная поддержка TypeScript.

Снятие типов рассчитано на минимальные накладные расходы: не поддерживаются конструкции, требующие генерации JavaScript-кода, а встроенные типы заменяются пробелами, поэтому Node.js может выполнять код TypeScript без карт исходников.

Снятие типов совместимо с большинством версий TypeScript; рекомендуется версия 5.8 или новее со следующими настройками tsconfig.json:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "compilerOptions": {
     "noEmit": true, // Optional - see note below
     "target": "esnext",
     "module": "nodenext",
     "rewriteRelativeImportExtensions": true,
     "erasableSyntaxOnly": true,
     "verbatimModuleSyntax": true
  }
}

Опцию noEmit имеет смысл включать, если вы только выполняете файлы *.ts, например скрипты сборки. Если вы планируете распространять файлы *.js, эта опция не нужна.

Выбор системы модулей

Node.js поддерживает в файлах TypeScript и CommonJS, и ES-модули. Node.js не преобразует одну систему модулей в другую: для ES-модуля нужны import и export, для CommonJS — require и module.exports.

  • Для файлов .ts система модулей определяется [так же, как для .js][the same way as .js files.]. Чтобы использовать import и export, добавьте "type": "module" в ближайший родительский package.json.
  • Файлы .mts всегда выполняются как ES-модули, аналогично .mjs.
  • Файлы .cts всегда выполняются как CommonJS, аналогично .cjs.
  • Файлы .tsx не поддерживаются.

Как и в JavaScript, в операторах import и выражениях import() расширения файлов обязательны: import './file.ts', а не import './file'. Из соображений обратной совместимости расширения обязательны и в вызовах require(): require('./file.ts'), а не require('./file'), по аналогии с обязательным .cjs в CommonJS.

Опция tsconfig.json allowImportingTsExtensions позволяет компилятору tsc проверять типы при импорте с указанием расширения .ts.

Возможности TypeScript

Node.js только удаляет встроенные типы; любые конструкции TypeScript, для которых нужно заменить синтаксис TypeScript на новый синтаксис JavaScript, приведут к ошибке.

Наиболее заметные случаи, требующие трансформации:

  • объявления enum
  • namespace с исполняемым кодом во время выполнения
  • свойства параметров конструктора (parameter properties)
  • псевдонимы импорта

namespace без исполняемого кода поддерживаются. Следующий пример будет работать:

1
2
3
4
// This namespace is exporting a type
namespace TypeOnly {
   export type A = string;
}

Ниже будет ошибка [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX][]:

1
2
3
4
// This namespace is exporting a value
namespace A {
   export let x = 1
}

Декораторы сейчас на стадии TC39 Stage 3, они не трансформируются и вызывают ошибку разбора. Node.js не подставляет полифиллы и не будет поддерживать декораторы до их нативной поддержки в JavaScript.

Кроме того, Node.js не читает tsconfig.json и не поддерживает возможности, зависящие от его настроек (paths, транспиляция нового синтаксиса в старый и т.д.).

Импорт типов без ключевого слова type

При снятии типов ключевое слово type нужно, чтобы корректно отделить импорты типов. Без type Node.js считает импорт значимым на этапе выполнения, что приведёт к ошибке. Поведение можно согласовать с опцией [verbatimModuleSyntax][].

Корректный пример:

1
2
import type { Type1, Type2 } from './module.ts';
import { fn, type FnParams } from './fn.ts';

Ниже будет ошибка времени выполнения:

1
2
import { Type1, Type2 } from './module.ts';
import { fn, FnParams } from './fn.ts';

Не файловый ввод

Снятие типов можно включить для --eval и STDIN. Система модулей определяется параметром --input-type, как для JavaScript.

Синтаксис TypeScript в REPL, --check и inspect не поддерживается.

Карты исходников

Встроенные типы заменяются пробелами, поэтому для корректных номеров строк в трассах стека карты исходников не нужны; Node.js их не генерирует.

Снятие типов в зависимостях

Чтобы авторы пакетов не публиковали код на TypeScript, Node.js не обрабатывает файлы .ts внутри каталогов по пути node_modules.

Псевдонимы путей

Настройка [tsconfig "paths"][] не трансформируется и приводит к ошибке. Ближайший аналог — подпути импорта, с ограничением: они должны начинаться с #.

Комментарии