Я сделал этот снимок с моего отпуска (я только что вернулся) на Менорке (Испания) из Кала Талайер . Удивительное место, но извините за слишком много синей насыщенности картинки. Я случайно не настроил камеру моего Nexus 4 должным образом и узнал ее позже в отеле. Тем не менее, этот пост посвящен не моим праздникам, а рассказу Хейлсберга о TypeScript на конференции Build в этом году. Находясь на этом пляже, я послушал разговор на своем планшете и записал несколько заметок.
Пост действительно не предназначен, чтобы отразить все детали разговора, а скорее некоторые ключевые моменты, которые кажутся мне интересными. TypeScript уже существует около 9 месяцев или около того, и мне нравится концепция, которая заключается в том, чтобы усовершенствовать инструментарий для JavaScript, но не заново изобретать новый язык, который компилируется в него. В любом случае, если вы хотите захватить все детали разговора, просто зайдите, чтобы прослушать его в полном объеме .
Основы
Основная задача TypeScript — добавить аннотации типов с целью улучшения инструментов JavaScript (таких как поддержка рефакторинга и т. Д.). Это означает, что вы получите некие «ошибки компиляции», а также сложную поддержку автозаполнения в Visual Studio. Но поскольку инструменты поддержки автозаполнения написаны на самом TypeScript , вы можете попробовать их непосредственно на площадке TypeScript и, возможно, в любой другой IDE. Так что это не просто специфично для VS, что является большим плюсом!
(Жирный минус: игровая площадка не отзывчива и не работает на моем планшете…)
Аннотация основного типа выглядит следующим образом
a: string
где a
— переменная JavaScript или параметр функции и string
соответствующий ей тип. Таким образом, использование этого выражения в функции приведет к следующему коду:
function(a: string) { ... }
Интерфейсы
Интерфейсы — это именно то, о чем вы сначала подумали. Они позволяют определить минимальный набор свойств или функций объекта. Это означает, что вы можете определить что-то вроде
interface Person { name: string; age: number; }
В результате объект персоны JavaScript должен иметь как минимум свойство a name
и, age
соответствующее определенным типам, но может иметь больше .
var a:Person = { name: 'Juri', age: 28 married: false }
Обратите внимание, что married
это не было определено в интерфейсе, но все еще допустимо объявить это ad-hoc при создании объекта JavaScript. Другая возможность — объявить необязательные элементы, которые добавляются с помощью ?
символа, такого как
interface Person { name: string; age: number; married?: boolean; }
Файлы определения TypeScript
Одним из приятных моментов является то, что вы можете добавить TypeScript в любой существующий код или библиотеку JavaScript, создав соответствующие файлы определения TypeScript. Они могут быть распределены по нескольким файлам, что облегчает захват модульной и динамической природы библиотек JavaScript. Таким образом, например, определения TypeScript для ядра jQuery определены в jquery.d.ts
то время, как любой другой плагин / расширение jQuery может предоставить свои собственные определения в отдельном файле, например myplugin.d.ts
.
Вы даже можете распространять определение одного TypeScript Interface
среди нескольких файлов. Это важно, если вы думаете о том, как плагины jQuery (но не только) динамически расширяют основной $
объект jQuery ( ).
Дженерики
JavaScript — это динамический язык, который имеет свои преимущества и недостатки. Одним из преимуществ динамического языка является то, что вы можете легко обобщить функцию, которая будет использоваться различными типами объектов и в разных контекстах, при условии, что они соответствуют требуемым функциям / свойствам, используемым в «универсальной» функции. Проблема в том, что, как только вы добавляете информацию о типах, вы возвращаетесь в «статически типизированный» мир, где вам нужны «обобщения», чтобы иметь возможность снова обобщать его для нескольких различных типов «типов».
К счастью, TypeScript также поддерживает Generics.
function sort<T>(a:T[]) : T[] { }
Тип возвращаемого значения (в данном случае массив типа T) обычно выводится автоматически, но также может быть объявлен явно (как в примере). При использовании обобщенных типов часто бывает необходимо указать «супертип», из которого должен генерироваться обобщенный тип, чтобы ограничить обобщенное использование только значимым подмножеством типов. Это делается следующим образом:
function sort<T extends Entity>(a:T[]) { }
Lamdas
Обычно, когда вы находитесь в контексте какого-либо объекта (в архитектуре MVC это обычно соответствует функции контроллера), чтобы получить доступ к исходному объекту из обратного вызова jQuery, вы должны «настроить» this
. Это часто делается так:
var someObject = { getName: function(){ return "Juri"; }, registerHandlers: function(){ var self = this; $(".js-say-hello").click(function(){ alert("Hi, my name is " + self.getName() + "!"); }); } };
Альтернативой является использование прокси-функции jQuery, но она все еще остается довольно громоздкой для написания.
TypeScript позволяет объявлять lamdas simlar тем, которые используются в C #. Их назначение следует предложению ES6 «исправить» this
в функциях обратного вызова.
registerHandlers: function(){ $(".js-say-hello").click(() => { alert("Hi, my name is " + this.getName() + "!"); }); }
За кулисами TypeScript переводит вышесказанное в
registerHandlers: function () { var _this = this; $(".js-say-hello").click(function () { alert("Hi, my name is " + _this.getName() + "!"); }); }
Ничего особенного, только то, что вы могли бы ввести вручную. Хорошая вещь (как упоминает Хейлсберг) состоит в том, что, как только ES6 можно будет безопасно использовать, TypeScript может просто удалить это преобразование, и ваш код продолжит работать.
Вывод
Как уже упоминалось, я нахожу концепцию, лежащую в основе TypeScript, довольно интересной. Одна из основных проблем, с которыми я часто сталкиваюсь, это отсутствие знаний об инструментах, которые есть у людей при разработке приложений JavaScript. Например, Chrome предоставляет множество расширенных инструментов для разработчиков, в которых также предусмотрена двусторонняя синхронизация между вашей файловой системой и браузером (например, с использованием расширения Tincr), а также широкие механизмы отладки и профилирования. Sublime Text на другой стороне — еще один пример отличного редактора JavaScript. К сожалению (особенно .Net) разработчики, привыкшие к Visual Studio, редко желают покинуть IDE и использовать внешний редактор только для того, чтобы иметь более сложную поддержку кодирования.
С другой стороны, есть поддержка рефакторинга в JavaScript. Sublime делает большую работу, помогая вам выполнять контекстный поиск и замену, но это не так надежно, как правильная функциональность рефакторинга.
Вот где я вижу потенциал TypeScript (особенно для корпоративной среды, в которой я работаю). С небольшим количеством свободного времени я мог бы видеть, могу ли я адаптировать его для CanJS (JavaScriptMVC), который является основой, которую мы используем для нашей разработки SPA.