Сучасні Node.js (з 22.18 і 23.6) запускають .ts файли напряму: перед виконанням вони просто стирають анотації типів, не перевіряючи їх і не компілюючи. Так само працюють швидкі інструменти на кшталт Bun, Deno та трансформацій у збирачах.
Що можна стерти - більша частина TypeScript: анотації, інтерфейси, type, generics, as, satisfies, import type. Після видалення лишається коректний JavaScript.
Що стерти неможливо - синтаксис, якому потрібна генерація коду:
enum- створює об'єкт під час виконання;namespaceз кодом усередині;- parameter properties (
constructor(private name: string)) - генерують присвоєння; import x = require('...'),export =;- старі декоратори з
emitDecoratorMetadata.
Прапорець erasableSyntaxOnly (TypeScript 5.8+) робить такий синтаксис помилкою компіляції - код гарантовано запуститься через стирання типів:
{
"compilerOptions": {
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true,
"noEmit": true
}
}
verbatimModuleSyntax доповнює його: імпорти лише типів мають бути явно позначені import type, щоб стирання не лишило імпорт неіснуючого значення.
Замінники:
// замість enum
const Role = { Admin: 'admin', Editor: 'editor' } as const;
type Role = (typeof Role)[keyof typeof Role];
// замість parameter properties
class User {
readonly id: number;
constructor(id: number) { this.id = id; }
}
Як це змінює роль tsc: компілятор дедалі частіше виконує лише перевірку типів (noEmit), а виконання й збирання роблять інші інструменти. TypeScript 7 (нативний компілятор на Go) робить таку перевірку в рази швидшою - і поділ «типи перевіряє tsc, код запускає рушій» стає типовою схемою.
Обмеження стирання типів у Node.js:
- типи не перевіряються під час запуску - помилки типів знайде лише
tsc; tsconfigігнорується -paths,baseUrl(у TypeScript 7 його вже немає) не працюють;- імпорти з розширенням
.ts- потрібноallowImportingTsExtensionsуtsconfigабо перезапис розширень (rewriteRelativeImportExtensions) при компіляції бібліотеки.
Висновок: для коду, який може запускатися без збирання (скрипти, сервіси на Node.js), «стираний» TypeScript - розумний стандарт. Для фронтенду через збирач обмеження м'якші, але й там enum і parameter properties дедалі частіше замінюють.
Докладніше в документації: TypeScript 5.8: erasableSyntaxOnly