Что такое TypeScript?

TypeScript — это бесплатный язык программирования с открытым исходным кодом, разработанный Microsoft. Он является надмножеством JavaScript, расширяющим синтаксис JavaScript.

Особенности синтаксиса

  • Классы
  • Интерфейсы
  • Модули
  • Аннотации типов
  • Проверка типов во время компиляции
  • Стрелочные функции (аналогично лямбда-выражениям C#)

Для получения дополнительных материалов, пожалуйста, обратитесь к:Учебник по TypeScript。

Разница между JavaScript и TypeScript

TypeScript — это надмножество JavaScript, расширяющее синтаксис JavaScript. Поэтому существующий код JavaScript может работать с TypeScript без каких-либо изменений. TypeScript обеспечивает статическую проверку типов во время компиляции с помощью аннотаций типов.

TypeScript может обрабатывать существующий код JavaScript и компилирует только код TypeScript внутри него.


Установка TypeScript

Установить TypeScript можно следующими двумя способами:

Интерфейс при установке через MSI-файл:

Шаги установки через npm:

1. Установите npm

$ curl http://npmjs.org/install.sh | sh
$  npm --version
2.15.1

2. Установите npm-пакет TypeScript:

$ npm install -g typescript

После установки можно использовать компилятор TypeScript под названием tsc, который может создавать js-файлы из результатов компиляции.

Чтобы скомпилировать файл TypeScript, используйте следующую команду:

tsc filename.ts

После успешной компиляции в том же каталоге будет создан js-файл с тем же именем. Вы также можете изменить имя выходного файла по умолчанию с помощью параметров команды.

По умолчанию компилятор ориентируется на ECMAScript 3 (ES3), но ES5 также является поддерживаемым вариантом. TypeScript добавляет поддержку возможностей, предложенных для будущего стандарта ECMAScript 6.


TypeScript Hello World

Сначала мы создаём файл index.html:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<title>Learning TypeScript</title>
</head> 
<body> 
    <script src="hello.js.html"></script>
</body> 
</html>

Создайте файл hello.ts. *.ts — это расширение файлов TypeScript. Добавьте следующий код в файл hello.ts:

alert('hello world in TypeScript!');

Затем мы открываем командную строку и используем команду tsc для компиляции файла hello.ts:

$ tsc hello.ts

В том же каталоге будет создан файл hello.js. Затем откройте index.html, и вывод будет следующим:


Аннотации типов

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

function Add(left: number, right: number): number {
    return left + right;
}

Аннотации для базовых типов — это number, bool и string. Слабая или динамическая структура типов — это тип any.

Аннотации типов можно экспортировать в отдельный файл объявлений, чтобы сделать доступной информацию о типах TypeScript-скриптов, которые используют типы и были скомпилированы в JavaScript. Аннотации можно объявить для существующей библиотеки JavaScript, как это сделано для Node.js и jQuery.

Когда типы не указаны, компилятор TypeScript использует вывод типов, чтобы вывести типы. Если тип не может быть выведен из-за отсутствия объявлений, по умолчанию используется динамический тип any.

Пример

Далее мы создаём простую функцию area() в файле TypeScript type.ts:

function area(shape: string, width: number, height: number) {
    var area = width * height;
    return "I'm a " + shape + " with an area of " + area + " cm squared.";
}
 
document.body.innerHTML = area("rectangle", 30, 15);

Далее изменитеindex.htmlфайл js наtype.jsЗатем скомпилируйте файл TypeScript:tsc type.ts。

Обновите файл index.html в браузере, и вывод будет следующим:


Интерфейс

Далее мы расширяем приведённый выше пример с помощью интерфейса. Создайте файл interface.ts и изменитеindex.htmlфайл js наinterface.js。

Код файла interface.js выглядит следующим образом:

interface Shape {
    name: string;
    width: number;
    height: number;
    color?: string;
}
 
function area(shape : Shape) {
    var area = shape.width * shape.height;
    return "I'm " + shape.name + " with area " + area + " cm squared";
}
 
console.log( area( {name: "rectangle", width: 30, height: 15} ) );
console.log( area( {name: "square", width: 30, height: 30, color: "blue"} ) );

Интерфейс может служить аннотацией типа.

Скомпилируйте приведённый выше кодtsc interface.tsОшибок не возникнет, но если вы добавите после приведённого выше кода инструкцию, в которой отсутствует параметр name, при компиляции будет сообщено об ошибке:

console.log( area( {width: 30, height: 15} ) );

Перекомпилируйте, и сообщение об ошибке будет следующим:

$ tsc hello.ts 
hello.ts(15,20): error TS2345: Argument of type '{ width: number; height: number; }' is not assignable to parameter of type 'Shape'.
  Property 'name' is missing in type '{ width: number; height: number; }'.

Обратитесь к нему в браузере, и вывод будет следующим:


Стрелочные функции (лямбда-выражения)

Лямбда-выражение()=>{something} или ()=>somethingОно эквивалентно функции в js. Его преимущество в том, что оно может автоматически привязывать this в функции к контексту.

Попробуйте выполнить следующее:

var shape = {
    name: "rectangle",
    popup: function() {
 
        console.log('This inside popup(): ' + this.name);
 
        setTimeout(function() {
            console.log('This inside setTimeout(): ' + this.name);
            console.log("I'm a " + this.name + "!");
        }, 3000);
 
    }
};
 
shape.popup();

В примере this.name имеет пустое значение:

Далее мы используем стрелочную функцию TypeScript. Заменитеfunction()на() =>:

var shape = {
    name: "rectangle",
    popup: function() {
 
        console.log('This inside popup(): ' + this.name);
 
        setTimeout( () => {
            console.log('This inside setTimeout(): ' + this.name);
            console.log("I'm a " + this.name + "!");
        }, 3000);
 
    }
};
 
shape.popup();

Вывод следующий:

В скомпилированном js-файле приведённого выше примера мы можем увидеть строкуvar _this = this;,_thisВ функции обратного вызова setTimeout() она ссылается на свойство name.


Класс

TypeScript поддерживает классы ECMAScript 6, которые включают поддержку необязательных аннотаций типов.

Далее мы создаём файл класса class.ts со следующим кодом:

class Shape {
 
    area: number;
    color: string;
 
    constructor ( name: string, width: number, height: number ) {
        this.area = width * height;
        this.color = "pink";
    };
 
    shoutout() {
        return "I'm " + this.color + " " + this.name +  " with an area of " + this.area + " cm squared.";
    }
}
 
var square = new Shape("square", 30, 30);
 
console.log( square.shoutout() );
console.log( 'Area of Shape: ' + square.area );
console.log( 'Name of Shape: ' + square.name );
console.log( 'Color of Shape: ' + square.color );
console.log( 'Width of Shape: ' + square.width );
console.log( 'Height of Shape: ' + square.height );

Приведённый выше класс Shape имеет два свойства, area и color, конструктор (constructor()) и метод shoutout().

Параметры (name, width и height) в конструкторе имеют локальную область видимости, поэтому при компиляции приведённого выше файла вывод ошибки в браузере выглядит следующим образом:

class.ts(12,42): The property 'name' does not exist on value of type 'Shape'
class.ts(20,40): The property 'name' does not exist on value of type 'Shape'
class.ts(22,41): The property 'width' does not exist on value of type 'Shape'
class.ts(23,42): The property 'height' does not exist on value of type 'Shape'

Далее мы добавляем модификаторы доступа public и private. К public-членам можно обращаться где угодно, а к private-членам — только внутри класса.

Далее мы изменяем приведённый выше код, объявляя color как private, а параметр конструктора name как public:

...
private color: string;
...
constructor ( public name: string, width: number, height: number ) {
...

Поскольку переменная-член color объявлена как private, появится следующее сообщение:

class.ts(24,41): The property 'color' does not exist on value of type 'Shape'

Наследование

Наконец, мы можем унаследовать существующий класс и создать производный класс. Наследование использует ключевое словоextends。

Далее мы добавляем следующий код в конец файла class.ts, как показано ниже:

class Shape3D extends Shape {
 
    volume: number;
 
    constructor ( public name: string, width: number, height: number, length: number ) {
        super( name, width, height );
        this.volume = length * this.area;
    };
 
    shoutout() {
        return "I'm " + this.name +  " with a volume of " + this.volume + " cm cube.";
    }
 
    superShout() {
        return super.shoutout();
    }
}
 
var cube = new Shape3D("cube", 30, 30, 30);
console.log( cube.shoutout() );
console.log( cube.superShout() );

Пояснение производного класса Shape3D:

  • Shape3D наследует класс Shape и также наследует свойство color класса Shape.
  • В конструкторе метод super вызывает конструктор Shape базового класса Shape, передавая значения параметров name, width и height. Наследование позволяет нам повторно использовать код класса Shape, поэтому мы можем вычислить this.volume, унаследовав свойство area.
  • Метод shoutout() класса Shape3D переопределяет реализацию базового класса. Метод superShout() напрямую возвращает метод shoutout() базового класса, используя ключевое слово super.
  • Для остальной части кода мы можем реализовать нужную функциональность в соответствии с нашими собственными потребностями.


Справочная документация