Статьи

TypeScript: масштабирование приложения, JavaScript

 

Я сделал этот снимок с моего отпуска (я только что вернулся) на Менорке (Испания) из Кала Талайер . Удивительное место, но извините за слишком много синей насыщенности картинки. Я случайно не настроил камеру моего 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.

Рекомендации