Зачем нужен TypeScript¶
У TypeScript есть две основные цели:
- Предоставить возможность опционального описания типов в JavaScript
- Предоставить возможность использовать сейчас улучшения, запланированные в будущих версиях JavaScript, посредством полифиллов.
Мотивация для достижения этих целей описана ниже.
Система типов TypeScript¶
Возможно, вы спросите "Зачем добавлять типы в JavaScript?"
Типизация позволяет улучшить качество и понимаемость кода. Большие команды (Google, Microsoft, Facebook) постоянно приходят к такому выводу. А именно:
- Типы повышают вашу гибкость при рефакторинге. Пусть лучше компилятор поймает ошибку, чем что-то сломается в рантайме
- Типы - это один из лучших, доступных вам видов документации. Сигнатура функции - это теорема, а тело функции - её доказательство.
Однако, типы могут быть излишне требовательными. TypeScript очень заботится о том, чтобы входной порог был как можно ниже. А именно:
Ваш JavaScript - это TypeScript¶
TypeScript обеспечивает для вашего кода на JavaScript типобезопасность во время компиляции. Учитывая его название, это неудивительно. Большое преимущество в том, что типы полностью опциональны. Ваш файл .js
с кодом на JavaScript может быть переименован в файл .ts
и TypeScript всё еще вернёт вам валидный .js
, эквивалентный оригинальному файлу JavaScript. TypeScript намеренно является строгой надстройкой над JavaScript с дополнительной проверкой Типов.
Типы могут быть Неявными¶
TypeScript будет пытаться вывести как можно больше информации о типах, чтобы предоставить вам типобезопасность с минимальными потерями продуктивности при написании кода. Например, в следующем примере TypeScript узнает, что тип foo будет number
и выдаст ошибку на второй строке:
1 2 3 4 |
|
Такой вывод типов имеет весомые основания. Если вы делаете как в примере выше, то вы не можете быть уверены, что далее в коде foo
будет number
или string
. Такие вопросы часто возникают в больших многофайловых кодовых базах. Позже мы рассмотрим правила вывода типов более подробно.
Типы могут быть Явными¶
Как мы уже сказали, TypeScript делает выводы максимально безопасно. Тем не менее, вы можете использовать аннотации, чтобы:
- Помочь компилятору и, что более важно, документировать код для разработчика, который будет читать код после вас (им может стать будущий вы!).
- Убедиться, что то, что видит компилятор и то, что вы задумали - это одно и то же. Таким образом, ваше понимание кода совпадает с алгоритмическим анализом кода (выполняемым компилятором).
TypeScript использует постфиксную аннотацию типов, популярную в других опционально аннотируемых языках (например, ActionScript и F#).
1 |
|
Так что, если вы ошибётесь, компилятор выдаст ошибку:
1 |
|
Мы подробно обсудим весь синтаксис аннотаций, поддерживаемый TypeScript в другой главе.
Типы являются структурными¶
В некоторых языках (особенно в номинально типизированных) статическая типизация приводит к ненужным церемониям, потому что даже если вы знаете, что код будет работать, семантика языка заставляет вас всюду копировать сущности. Поэтому такие вещи, как автомаппер для C# жизненно необходимы для C#. В TypeScript типы являются структурными, потому что мы действительно хотим, чтобы для разработчиков JavaScript это было просто и с минимумом когнитивной нагрузки. Это значит, что утиная типизация - это языковая конструкция первого класса. Рассмотрим следующий пример. Функция iTakePoint2D
примет всё, что содержит элементы, которые она ожидает (x
and y
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Ошибки типов не мешают выводу JavaScript¶
Чтобы вам было проще мигрировать с JavaScript, по умолчанию TypeScript выдаст настолько валидный JavaScript, насколько сможет, даже если есть ошибки компиляции. Например:
1 2 |
|
выдаст следующий js:
1 2 |
|
Так что вы можете инкрементально обновлять ваш код с JavaScript на TypeScript. В этом важное отличие от того, как работают многие другие компиляторы и это еще одна причина перейти на TypeScript.
Типы могут быть фоновыми¶
Основной целью дизайна TypeScript была возможность просто и безопасно использовать существующие библиотеки JavaScript. TypeScript реализует это с помощью декларации. TypeScript предоставляет вам широкий спектр того, насколько мало или много усилий вы хотите потратить на декларации; чем больше вы потратите, тем более типобезопасный и понятный код вы получите. Заметьте, что определения для большинства популярных библиотек JavaScript уже были написаны для вас сообществом DefinitelyTyped, поэтому в большинстве случаев либо:
- Файл дефиниций уже существует.
- Либо, как минимум, у вас есть большой список уже готовых проверенных шаблонов деклараций TypeScript
В качестве быстрого примера того, как вы можете написать свой файл деклараций, рассмотрим простой пример jquery. По умолчанию (что и ожидается от хорошего кода JS) TypeScript ожидает объявления (т.е. использования где-нибудь var
) перед тем как использовать переменную:
1 |
|
Для исправления вы можете рассказать TypeScript, что тут есть что-то под названием $
:
1 2 |
|
Если хотите защититься от ошибок, то можно предоставить больше информации, опираясь на это определение:
1 2 3 4 5 |
|
Мы обсудим подробности создания определений TypeScript для существующего JavaScript позже, когда вы больше узнаете о TypeScript (такие вещи как interface
и any
).
Будущее JavaScript => Сейчас¶
TypeScript предоставляет множество особенностей, запланированных в ES6 и в текущих движках JavaScript (которые поддерживают только ES5 и др.). Команда TypeScript активно добавляет эти фичи и их список со временем будет только расти, о чем мы расскажем в соответствующем разделе. В качестве образца здесь приведен пример класса:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
и любимая стрелочная функция:
1 |
|
Резюме¶
В этом разделе мы рассказали о движущей силе и дизайне TypeScript. Разобравшись с этим, мы можем погружаться в мельчайшие подробности TypeScript.