Какие сущности TypeScript остаются в рантайме после транспиляции
Что проверяют
Понимаете ли вы, что TypeScript в основном стирает типы, но часть конструкций порождает настоящий JavaScript. Следом обычно спрашивают, почему нельзя проверить instanceof на интерфейсе и что не так с enum.
Как отвечать
Бесследно исчезает всё, что относится к системе типов: interface, type, дженерики, аннотации, as, satisfies, !, declare, модификаторы public, private, protected, readonly, import type. Предикат x is User стирается, а сама функция-гард остаётся.
В рантайм попадает:
enum: превращается в объект, у числового ещё и обратное отображение (Color[0] === "Red").const enumtsc подставляет значениями в места использования, объект сохраняется только сpreserveConstEnums;- классы: это JavaScript, они остаются, включая
abstract-классы, у которых пропадают лишь абстрактные члены. Parameter properties (constructor(private api: Api)) разворачиваются в присваиваниеthis.api = api; namespaceсо значениями: компилируется в IIFE и объект;- декораторы: остаются вызовами функций, и стандартные из TypeScript 5.0, и старые
experimentalDecorators. СemitDecoratorMetadataдобавляются ещё метаданные типов, на которых держится DI в Angular и NestJS; - поля
#private: нативный JavaScript, в отличие от модификатораprivate; importиexport: остаются, если импорт используется как значение. СverbatimModuleSyntaxкомпилятор сохраняет всё, что не помеченоtype.
Сильное дополнение: свежий Node.js запускает .ts, просто вырезая типы, так же работают esbuild и SWC в пофайловом режиме. enum, namespace и parameter properties такой режим по умолчанию не поддерживает, и флаг erasableSyntaxOnly из TypeScript 5.8 запрещает именно их.
Где спотыкаются
Говорят, что enum исчезает как тип. Он остаётся объектом, увеличивает бандл и плохо удаляется tree shaking.
Пытаются проверять интерфейс в рантайме. Для этого нужен свой type guard или схема валидации вроде Zod.
Считают, что private защищает поле. После компиляции оно обычное и доступно любому коду, настоящую приватность даёт только #.