🤓Дизайн современного TypeScript стремиться в направление "всего лишь типы".



Это означает, что ЯП почти не вводит собственных Runtime конструкций. Все что нужно, чтобы преобразовать TypeScript в JavaScript - это просто удалить типовые декларации и аннотации. И это используется такими инструментами, как ESBuild или SWC, чтобы добиться более быстрой сборки кода.



Однако, я сказал "почти". Дело в том, что в TS все таки есть такие конструкции, которые нельзя преобразовать в JS простым удалением кода. Давайте приведем примеры.



1. Поля класса через аргументы конструктора.



class User {

constructor(public name: string, private age: number) {}

}




И аналог на JS.



class User {

#age;

constructor(name, age) {

this.name = name;

this.#age = age;

}

}




2. Декораторы - уже нет. Начиная с TS5 декораторы в TS соответствует тому, как они описываются в стандарте JS. Да, спека декораторов еще не вошла в стандарт, но она находится на пред-финальной стадии полировки, так что скоро можем ожидать и нативную поддержку.



3. Пространства имен.



namespace MyNamespace {

export function myFunction() {

console.log("Hello, world!");

}

}




И аналог на JS (обычный паттерн модуль):



var MyNamespace;

(function (MyNamespace) {

function myFunction() {

console.log("Hello, world!");

}



MyNamespace.myFunction = myFunction;

})(MyNamespace || (MyNamespace = {}));




4. Enum. Особый вид словаря. Также является типом-суммой.



enum PromiseState {

pending,

fulfilled,

rejected

}



enum HTTPStatuses {

ok = 200,

notFound = 404

}



enum Users {

bob = 'Bob Hilton',

ben = 'Ben Tompson'

}




И аналог на JS:



const PromiseState = {

pending: 0,

0: 'pending',

fulfilled: 1,

1: 'fulfilled',

rejected: 2,

2: 'rejected'

};



const HTTPStatuses = {

ok: 200,

200: 'ok',

notFound: 404,

404: 'notFound'

};



const Users = {

bob: 'Bob Hilton',

ben: 'Ben Tompson'

};




Обратите внимание, что последний Enum транслируется 1 в 1 как простой объект JS. А в остальных случаях, у нас получается словарь, где есть отображение как для значений, так и для ключей, что бывает весьма удобно. Плюс, если мы явно не указываем значение в enum, то оно генерируется как целое не отрицательное число. Получается, что enum это такой типизированный словарь возможных значений типа. Удобно, но настолько ли, что оно стоило добавления в Runtime? В добавок тут есть и ложка дегтя: к enum не применим spread (...) оператор и нет аналога extends. Т.е. наследование перечислений на чистом ТС невозможно. Чтобы объехать, придется писать хэлперы.



5. Const Enum. Самый интересный вид Enum. Давайте рассмотрим на примере:



const enum HTTPStatuses {

ok = 200,

notFound = 404

}



console.log(HTTPStatuses.ok);




И аналог на JS:



console.log(200);




Ого! В Runtime const enum вообще не представляется, т.е. это исключительно design time структура.



В остальном ТС такой же JS с точки зрения runtime. И вот тут возникает проблема: дело в том, что из-за этих 4-х пунктов (декораторы я вычеркнул) полностью корректное преобразование TS в JS сильно усложняется. Поэтому мы и видим на сайте многих инструментов, по типу SWC, что: "часть фишек ТС мы не поддерживаем". И это проблема. Ведь даже если вы их не используете, то их могут использовать другие.



И стоило оно того? Ну сахар, но не такой уж и значимый. Может нужно пометить его как deprecated и потом удалить? Предлагаю вам поварить эту мысль в голове. А я пока кину затравку на следующую статью: я расскажу вам как с помощью Enum можно радикально ускорить ваш код и уменьшить потребление памяти. В моем случае ускорение было 4-х кратным!



Хаки? Магия? Продолжение следует...