среда, 21 марта 2018 г.

Введение в TypeScript


TypeScript одна из многих попыток сделать JavaScript лучше.
«Ой, я использую Gulp по причине A» или «Ой, я использую Redux по причине Б». Вы постоянно слышите подобные разговоры среди разработчиков фронт-енда. Сейчас становится популярно использовать новые фишки для того что бы скрыть недостатки JavaScript, и в этом нет ничего плохого. Даже появление ES2015 и последующих его обновлений является решительной попыткой исправить эти ошибки.
TypeScript – это обещающее изменение для нашего любимого языка, которое можеть серьёзно повлиять на наше будущее.

Так что такое TypeScript?
TypeScript – это строго-типизированое подмножество JavaScript, это значит, что он добавляет синтаксические преимущества языку, позволяя при этом писать на привычном JavaScript если вам этого хочется. Он поддерживает более декларативный стиль программирования через такие вещи как интерфейсы и статические типы (более подробно об этом далее), предлагает использовать модули и классы, и что более важно, достаточно хорошо интегрируется с популярными библиотеками и кодом. Вы можете будмать о нем как строго-статическая прослойка над текущим JavaScript, которая содержит некоторые возможности, позволаяющие сделать вашу жизнь (и особенно отладку) немножко более терпимой.
TypeScript получил внимание несколько лет назад изза того, что он был выбран для полной поддержки фреймворков Angular 2 и его последующими версиями (которые также написаны на TypeScript). Он также разрабатывается Microsoft, а это значит что он имеет за плечами поддержку двух огромных компаний (не так уж и плохо для любого языка). С этого времени, он получает все больше последователей и статус мейнстрима.

Разумеется, на TypeScript стоит обратить внимание.
Как это работает?
TypeScript на самом деле выглядит как современный JavaScript. На самом простом уровне, он предоставляет парадигму статической типизации для JavaScript, таким образом вместо того что бы писать:
var name = “Susan”,
    age = 25,

    hasCode = true;
Мы может написать:
let name: string = "Susan",
    age: number = 25,

    hasCode: boolean = true;
Как вы видите, здесь не так много отличий. Все чт мы делаем – это явно говорим системе какой тип следует использовать для каджой переменной, мы рассказываем об этом с самого начала, что name это строка, а age  это число. Но это только кажется что кода нужно писать больше. Зачем вообще нам говорить системе о такой специфической информации? Потому что это дает системе больше информации о программе, которая в свою очередь помогает отловить ошибки которые могут возникнуть позднее.
Представьте, например, что у вас есть такой код:

var age = 25;

age = "twenty-five";
Изменение переменной подобным образом и изменение ее типа наверняка приведет к тому что где-то что то поломается, особенно если речь идеть о большой программе, поэтому было бы здорово, если бы компилятор мог отловить проблему до того, как этот код будет загружен в браузер, и мы вынуждены будем сидеть полчаса и разбираться с проблемой сами. Словом, это делает нашу программу более безопасной и защищенной от подобных проблем.
Но это не все. Вот пример с руководства по TypeScript с сайта (который вы можете найти здесь)
interface Person {
    firstname: string;
    lastname: string;
} 
function greeter(person : Person):string {
    return "Hello, " + person.firstname + " " + person.lastname;
}
let user = {firstname: "Jane", lastname: "User"};

document.body.innerHTML = greeter(user);
Теперь у нас есть еще несколько необычных вещей, в добавок к тому о чем мы говорили ранее. У нас есть объект user, который содержит имя и фамилию, и эта информация передается методу greeter(), который присваивает эту информацию телу документа. Но здесь есть некоторые странные вещи в аргументе функции greeter, и что то непонятное под названием interface.
Давайте начнем с функции greeter:
function greeter(person: Person):string {
    return "Hello, " + person.firstname + " " + person.lastname;

}
Вы можете видеть, что функция greeter  принимает параметр person  и мы ожидаем что тип параметра будет Person. Таким образом, мы можем быть уверены, что когда нам понадобиться узнать имя этого человека, то такое поле определенно будет у данного объекта, и нам не нужно ломать голову пытаясь убедится в этом. :string  после параметра функции говорит нам о типе возвращаемого функцией значения.
В теле функции нету ничего сложного, но разумеется, теперь вы наверняка хотели бы знать, что в действительности представляет собой тип Person. И здесть на помощь приходит ключевое слово interface.
interface Person {
    firstname: string;
    lastname: string;

}
Интерфейсы используются в TypeScript для оперделения структуры объектов (и только объектов). В нашем примере, мы говорим, что любая переменная типа должна иметь поля firstname  и lastname, каждый из которых имеет строковый тип. Так мы создаем произвольный тип для нашего объекта.

Это чрезвычайно полезно, так как мы говорим компилятору, и себе, а также разработчику, который будет работать с этим кодом в будущем, с каким типом данных будет работать наш код. Таким образом мы моделируем свойства объекта, и создаем что-то на что впоследствии можно ссылаться при отладке. Именно по этому интерфейсы как правило описываются вначале файла, поскольку они дают информацию о данных, которые испрользуются в коде далее.
В нашем случае, если мы используем интерфейс Person с переменной в любой точке программы и он не содержит ни firstname  ни lastname, каждый из которого является строкой (к счастью у нашего user  с этим все впорядке), то компилятор будет жаловаться и нам придется чинить код.
Не только это, но имея статическую типизацию среда разработки, которая поддерживает TypeScript может давать нам очень хорошие подсказки и авто-дополнения в процессе написания кода, и это позволить нам получить более эфективный и безопасный процесс разработки.

Существует намного больше возможностей, которые появляются с использованием TypeScript, например шаблоны и пространства имен, таким образом я настоятельно рекомендую ознакомиться с документацией.
Как он устанавливается?
Из-за того что TypeScript – это подмножество JavaScript, то нам нужно преобразовать его в JavaScript, если мы хотим использовать его в браузере. К счастью, он имеет встроенную поддержку интегрирации с некоторым числом планировщиков задач и менеджером пакетов.
Если вы только хотите посмотреть на язык в деле и приобрести первоначальную практику, вы можете установить его глобально используя npm и далее пользоваться командной строкой и командой  tsc:

tsc your-typescript-file.ts
Эта команда сгенерирует файл JavaScript,  который в данном случае будет называтся your-typescript-file.js, и его можно использовать в браузере как обычно. Однако при настройке в проекте, почти наверняка будет задан правильный tsconfig.json.
Этот файл говорит о том, что данный проект использует TypeScript, и это позволяет иметь дополнительные настройки для языка.Ниже представлен частичный пример из документации:
{
    "compilerOptions": {
        "module": "commonjs",
        "outFile": "./build/local/tsc.js",
        "sourceMap": true
    },
    "exclude": [
        "node_modules"
    ]

}
Здесь мы можем конфигурировать компилятор разными способами. Мы может определять модули для компиляции, местоположение скомпилированных файлов, когда их требуется дополнительно обрабатывать позже. Мы можем указать exclude  настройки, которые говорят компилятору обрабатывать все файлы с расширением .ts – все файлы кроме тех которые находятся в папке node_modules  будут скомпилированы.

Продолжая эту тему, мы можем интегрировать весь процесс в наш любимый планировщик задач или менеджер пакетов. И Grunt и Gulp имеют плагины для TypeScript, которые можно указть в настройке этих инструментов. Webpack имеет в своем арсенале замечательный загрузчик TypeScript, и много других полезных настроек. Одним словом вы можете интегрировать в свой процесс поддержку TypeScript самыми разнообразными способами без каких то существенных трудозатрат.
Внешняя типизация
Если вы используете внешние библиотеки в вашем проекте (давайте смотретьправде в глаза, кто-же их не использует?) то вам необходимо иметь определения типов для этой библиотеки. Эти определения как правило хранятся в файле с расширением .d.ts  – они дают доступ к интерфейсам которые другие люди используют в других библиотеках. Подобные определения доступны в большом хранилище которое называется DefinitelyTyped, откуда все можно установить.
Для того что бы получить доступ  к данному хранилищу, вам необходимо установить Typings, который похож на аналог для npm но предназначен для определений типов TypeScript. Он имеет собственный файл настоек typings.json, где вы можете сконфигурировать пакеты и пути для ваших установок.
Мы не будем сильно подробно останавливаться на данном аспекте, но если хотите использовать типы AngularJS 1.x, к примеру, то вам нужно всего лишь выполнить команду typings install angularjs --save, все определния типов будут установлены по пути которые указаны в typings.json. После этого вы можете использовать типы и Angular везде где захотите в вашем проекте, просто добавляя такую строку:

/// <reference path="angularjs/angular.d.ts" />
Теперь мы может использовать типы как показано ниже:

var http: ng.IHttpService;

Хорошо, а что насчет сообщества?
Сообщество TypeScript продолжает расти, с увеличеим использования языка. Хотя пожалуй самое важное, что на нем написан Angular 2+ и фреймворк обеспечивает полную поддержку языка с самого начала. Также есть фантастическая поддержка синтаксиса в Microsoft Visual Studio IDE и Visual Studio Code, с пакетам и плагинами для редактирования такими как Atom, Sublime Text и Emacs.
Это означает, что вокруг TypeScript ведется много активности, поэтому вам нужно следить за всем происходящим.

Дальнейшее Чтение

·        DefinitelyTypedсторонние определения TypeScript


Выводы
TypeScript – это интересный способ улучшения недостатков JavaScript, посредством введения статической системы типов с интерфейсами и объединениями типов. Это помогает нам писать более безопасный, понятный и декларативный код.
Он хорошо интегрируется практически c любой популярной в настоящий момент build-системой и даже дает нам возможность создавать и использовать пользовательские типы. Есть также множество IDE и текстовых редакторов, которые отлично поддерживают синтаксис и процесс компиляции, поэтому вы можете использовать его в своей среде разработки с минимальными трудозатратами.
Возможно, самое главное, TypeScript является большой частью Angular 2+, что означает, что мы будем видеть язык и в будущем. Чем больше мы знаем об нем и о том, как он работает, тем лучше мы будем им пользоваться, когда он станет полноценной альтернативой JavaScript.
Вы чувствуете себя вдохновленным и собираетесь использовать TypeScript в своем следующем проекте? Является ли язык будущим JavaScript, или это просто причуда? Пишите что вы думаете в коментариях ниже!