TypeScript — как JavaScript, но может больше

JavaScript созда­ва­ли для про­стых скрип­тов в вебе, поэто­му авто­ры сде­ла­ли серию допу­ще­ний, что­бы его мож­но было быст­ро осво­ить. Но посте­пен­но язык стал очень вос­тре­бо­ван­ным, его нача­ли исполь­зо­вать бук­валь­но вез­де, и на боль­ших про­ек­тах нача­ли появ­лять­ся проблемы.

На помощь при­хо­дит TypeScript — язык, кото­рый в 2012 году раз­ра­бо­та­ли в Microsoft. Он реша­ет неко­то­рые недо­стат­ки JavaScript, при этом не тре­бу­ет осо­бых уси­лий для изу­че­ния. Посмот­рим на неко­то­рые отли­чия это­го язы­ка от при­выч­но­го JS.

Строгие типы данных

Одна из осо­бен­но­стей JavaScript — дина­ми­че­ская типи­за­ция. Тип пере­мен­ных зада­ёт­ся нестро­го, из-за это­го, напри­мер, в любом участ­ке кода чис­ло мож­но пре­вра­тить в стро­ку. Это не осо­бо страш­но, если один раз­ра­бот­чик дела­ет неболь­шой про­ект для сай­та и хоро­шо раз­би­ра­ет­ся в коде. А вот в боль­ших про­ек­тах может при­ве­сти к ошибкам.

JavaScript для нович­ков: чем опас­ны нестро­гие типы данных →

В TypeScript типи­за­ция стро­гая — ука­зать тип пере­мен­ной нуж­но при её созда­нии, а изме­нить в буду­щем нель­зя. Например:

let a: string; // Заве­ли пере­мен­ную «a» и ука­за­ли, что это стро­ка. Теперь она оста­нет­ся стро­кой и не пре­вра­тит­ся слу­чай­ным обра­зом в число

Если нуж­но, то мож­но задать пере­мен­ную, у кото­рой может быть любой тип. Если это потре­бу­ет­ся, его мож­но изме­нить во вре­мя рабо­ты системы:

let any: any; // Заве­ли пере­мен­ную any, у кото­рой может быть любой тип

В TypeScript есть типы дан­ных, кото­рых нет в JavaScript. Напри­мер, enum — перечисление:

enum iPhonePrice {

XR = 799,

XI = 899,

XII = 999}; // Созда­ли пере­чис­ле­ние iPhone с цена­ми на воз­мож­ные варианты

В буду­щем мож­но вызвать это пере­чис­ле­ние и под­ста­вить значение:

let total: number = iPhonePrice.XR; // Созда­ли пере­мен­ную total, ука­за­ли, что она — чис­ло, и зада­ли ей в каче­стве зна­че­ния сто­и­мость iPhone XR.

Поиск ошибок прямо в IDE

Най­ти ошиб­ки, свя­зан­ные с дина­ми­че­ской типи­за­ци­ей, в JavaScript мож­но толь­ко тогда, когда код уже напи­сан, — для это­го при­дёт­ся его где-то запу­стить. С TypeScript всё по-другому, код про­ве­ря­ет­ся пря­мо в редак­то­ре, на лету.

Писать на TypeScript мож­но в любом соф­те, кото­рый пони­ма­ет язык из короб­ки или с помо­щью внеш­не­го пла­ги­на. Напри­мер, Sublime, VSC или Atom. Вот как поиск оши­бок рабо­та­ет в Visual Studio Code. Возь­мём для при­ме­ра ts-проект с дву­мя пере­мен­ны­ми: a и b, где a — это стро­ка, а b — число:

Вот как поиск ошибок работает в Visual Studio Code

Попро­бу­ем при­сво­ить пере­мен­ной «a» зна­че­ние 12.

Попробуем присвоить переменной «a» значение 12

В редак­то­ре высве­чи­ва­ет­ся ошибка:

TypeScript — как JavaScript, но может больше: В редакторе высвечивается ошибка

TypeScript под­ска­зы­ва­ет, что мы не можем задать зна­че­ние 12 для пере­мен­ной «a». Пото­му что «a» долж­но быть стро­кой, а 12 — чис­ло. Попро­бу­ем при­сво­ить не 12, а “12”, и ошиб­ка пропадёт.

Интерфейсы и классы

В TypeScript луч­ше реа­ли­зо­ва­ны неко­то­рые идеи ООП, напри­мер, клас­сы и интерфейсы. 

Интер­фейс — спо­соб опи­сать фор­му объ­ек­та — спи­сок свойств и их тип. Напри­мер, созда­дим интер­фейс пользователя:

interface IUser {

     name: string,

     age: number,

}

Теперь мож­но создать с помо­щью это­го интер­фей­са ново­го пользователя:

const alexey: IUser = {

     name: Alexey,

     age: 18,

}

Интер­фей­сы помо­га­ют избе­гать оши­бок. Быва­ет, что про­грам­мист созда­ёт объ­ект, но добав­ля­ет в него какое-то новое свой­ство или опе­ча­ты­ва­ет­ся в назва­нии ста­ро­го. В клас­си­че­ском JS это не оста­но­вит выпол­не­ние про­грам­мы — про­сто в объ­ек­те появит­ся еще одно свой­ство, но уже с опе­чат­кой. И даль­ше в коде будут необъ­яс­ни­мые ошиб­ки, кото­рые будет очень труд­но отловить. 

С типи­за­ци­ей нако­ся­чить слож­нее — если опе­ча­тал­ся в назва­нии свой­ства, появит­ся ошибка. 

Созда­дим интер­фейс поль­зо­ва­те­ля с поля­ми «Имя» и «Воз­раст», а затем на его осно­ве — поль­зо­ва­те­ля Alexey со свой­ства­ми «Имя», «Воз­раст» и «Пол». Редак­тор кода пору­га­ет­ся — в интер­фей­се тре­тье­го свой­ства нет:

TypeScript — как JavaScript, но может больше: Создадим интерфейс пользователя с полями «Имя» и «Возраст

Что такое клас­сы в объектно-ориентированном программировании →

Обратная совместимость

После ком­пи­ля­ции кода на TypeScript созда­ёт­ся обыч­ный код JavaScript, кото­рый мож­но сра­зу исполь­зо­вать в про­ек­те. Пере­пи­сать про­ект на TS мож­но бук­валь­но по частям: поти­хонь­ку пере­ра­ба­ты­вать моду­ли один за дру­гим, когда на это будут ресур­сы. Ника­ких кон­флик­тов не возникнет.

Эту ста­тью мы напи­са­ли по моти­вам интер­вью с Алек­сан­дром Шты­ко­вым — фронтенд-лидом Дело­вой Сре­ды. С недав­них пор TypeScript стал стан­дар­том во всех про­ек­тах, над кото­ры­ми рабо­та­ют коман­ды Александра.

Почи­тай­те про его карьер­ный путь и тех­но­ло­гии, кото­рые он изу­чил, что­бы дорас­ти от контент-менеджера до тех­ни­че­ско­го руководителя →

Экс­перт:
Алек­сандр Штыков

Текст и иллю­стра­ции:
Сла­ва Уфимцев

Редак­тор:
Мак­сим Ильяхов

Кор­рек­тор:
Ири­на Михеева

Худож­ник:
Даня Бер­ков­ский

Вёрст­ка:
Мария Дро­но­ва

Соц­се­ти:
Олег Веш­кур­цев

Во имя:
стро­гих типов данных