Advertisement
  1. Code
  2. JavaScript

Начинаем работу с TypeScript

Scroll to top
Read Time: 10 min

() translation by (you can also view the original English article)

В конце 2012 года Microsoft представила TypeScript, типизированный суперсет для JavaScript, который компилируется в обычный JavaScript. TypeScript фокусируется на предоставлении полезных инструментов для крупномасштабных приложений путем реализации функций, таких как классы, аннотации типов, наследование, модули и многое другое! В этом уроке мы начнем с TypeScript, используя простые примеры кода с укусом, скомпилируем их в JavaScript и просмотрим мгновенные результаты в браузере.


Установка инструментов

Возможности TypeScript применяются только во время компиляции.

Вы настроите свою машину в соответствии с вашей конкретной платформой и потребностями. Пользователи Windows и Visual Studio могут просто загрузить плагин Visual Studio. Если вы работаете в Windows и не имеете Visual Studio, попробуйте Visual Studio Express для Интернета. Опыт TypeScript в Visual Studio в настоящее время превосходит другие редакторы.

Если вы работаете на другой платформе (или не хотите использовать Visual Studio), все, что вам нужно, это текстовый редактор, браузер и пакет npm для TypeScript для использования TypeScript. Следуйте инструкциям по установке:

  1. Установка диспетчера пакетов node (npm)
    1
      	$ curl http://npmjs.org/install.sh | sh
    
    2
    		$ npm --version
    
    3
    		1.1.70
    
  2. Глобально установите TypeScript пакет npm:
    1
    		$ npm install -g typescript
    
    2
    		$ npm view typescript version
    
    3
    		npm http GET https://registry.npmjs.org/typescript
    
    4
    		npm http 304 https://registry.npmjs.org/typescript
    
    5
    		0.8.1-1
    
  3. Любой современный браузер: для этого учебника мы используем Chrome.
  4. Любой текстовый редактор: для этого учебника используется Sublime Text
  5. Модуль подсветки синтаксиса для текстовых редакторов

Готово; мы готовы сделать простое приложение «Hello World» в TypeScript!


Hello World в TypeScript

TypeScript является надмножеством Ecmascript 5 (ES5) и включает функции, предлагаемые для ES6. Из-за этого любая программа JavaScript уже является программой TypeScript. Компилятор TypeScript выполняет локальные преобразования файлов в программах TypeScript. Следовательно, окончательный вывод JavaScript точно соответствует вводу TypeScript.

Сначала мы создадим базовый файл index.html и ссылку на внешний файл сценария:

1
<!doctype html>
2
<html lang="en">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>Learning TypeScript</title>
6
</head>
7
<body>
8
9
	<script src="hello.js"></script>
10
11
</body>
12
</html>

Это простое приложение «Hello World»; поэтому давайте создадим файл с именем hello.ts. Расширение *.ts обозначает файл TypeScript. Добавьте следующий код в hello.ts:

1
alert('hello world in TypeScript!');

Затем откройте интерфейс командной строки, перейдите к папке, содержащей hello.ts, и запустите компилятор TypeScript с помощью следующей команды:

1
tsc hello.ts

Команда tsc является компилятором TypeScript и сразу генерирует новый файл hello.js. В нашем приложении TypeScript не используется синтаксис, специфичный для TypeScript, поэтому мы видим тот же самый код JavaScript в hello.js, который мы написали на hello.ts.

Круто! Теперь мы можем изучить возможности TypeScript и посмотреть, как это может помочь нам поддерживать и создавать широкомасштабные приложения JavaScript.


Аннотации type

Аннотации типа являются дополнительной функцией, которая позволяет нам проверять и выражать наше намерение в программах, которые мы пишем. Давайте создадим простую функцию area() в новом файле TypeScript, называемом type.ts

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

Затем измените источник скрипта в index.html на type.js и запустите компилятор TypeScript с помощью tsc type.ts. Обновите страницу в браузере, и вы увидите следующее:

Как показано в предыдущем коде, аннотации типа выражаются как часть параметров функции; они указывают, какие типы значений вы можете передать функции. Например, параметр shape обозначается как строковое значение, а width и height - это числовые значения.

Аннотации типов и другие функции TypeScript применяются только во время компиляции. Если вы передадите какие-либо другие типы значений этим параметрам, компилятор даст вам ошибку времени компиляции. Такое поведение чрезвычайно полезно при создании крупномасштабных приложений. Например, давайте намеренно передать строковое значение для параметра width:

1
function area(shape: string, width: number, height: number) {
2
	var area = width * height;
3
	return "I'm a " + shape + " with an area of " + area + " cm squared.";
4
}
5
6
document.body.innerHTML = area("rectangle", "width", 15); // wrong width type

Мы знаем, что это приводит к нежелательному результату, и компиляция файла предупреждает нас о проблеме со следующей ошибкой:

1
$ tsc type.ts
2
type.ts(6,26): Supplied parameters do not match any signature of call target

Обратите внимание, что, несмотря на эту ошибку, компилятор сгенерировал файл type.js. Ошибка не останавливает компилятор TypeScript от генерации соответствующего JavaScript, но компилятор предупреждает нас о потенциальных проблемах. Мы предполагаем, что width будет числом; передача чего-либо другого приводит к нежелательному поведению в нашем коде. Другие аннотации типа включают bool или даже any.


Интерфейсы

Давайте расширим наш пример, включив интерфейс, который далее описывает форму как объект с дополнительным свойством color. Создайте новый файл с именем interface.ts и измените источник скрипта в index.html, чтобы включить interface.js. Введите следующий код в interface.ts:

1
interface Shape {
2
	name: string;
3
	width: number;
4
	height: number;
5
	color?: string;
6
}
7
8
function area(shape : Shape) {
9
	var area = shape.width * shape.height;
10
	return "I'm " + shape.name + " with area " + area + " cm squared";
11
}
12
13
console.log( area( {name: "rectangle", width: 30, height: 15} ) );
14
console.log( area( {name: "square", width: 30, height: 30, color: "blue"} ) );

Интерфейсы - это имена, присвоенные типам объектов. Мы можем не только объявить интерфейс, но и использовать его как аннотацию типа.

Компиляция interface.js не приводит к ошибкам. Чтобы вызвать ошибку, добавим еще одну строку кода в interface.js с формой, которая не имеет свойства имени и посмотрим результат в консоли браузера. Добавьте эту строку в interface.js:

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

Теперь скомпилируйте код с помощью tsc interface.js. Вы получите сообщение об ошибке, но не беспокойтесь об этом прямо сейчас. Обновите свой браузер и посмотрите на консоль. Вы увидите что-то похожее на следующий снимок экрана:

Теперь давайте посмотрим на ошибку. Это:

1
interface.ts(26,13): Supplied parameters do not match any signature of call target:
2
Could not apply type 'Shape' to argument 1, which is of type '{ width: number; height: number; }'

Мы видим эту ошибку, поскольку объект, переданный в area(), не соответствует интерфейсу Shape; для этого требуется свойство name.


Стрелочные функции

Понимание сферы действия ключевого слова this является сложной задачей, и TypeScript упрощает его, поддерживая выражения стрелочных функций, новую возможность, обсуждаемую для ECMAScript 6. Стрелочные функции сохраняют значение this, что значительно упрощает запись и использование функций обратного вызова. Рассмотрим следующий код:

1
var shape = {
2
	name: "rectangle",
3
	popup: function() {
4
5
		console.log('This inside popup(): ' + this.name);
6
7
		setTimeout(function() {
8
			console.log('This inside setTimeout(): ' + this.name);
9
			console.log("I'm a " + this.name + "!");
10
		}, 3000);
11
12
	}
13
};
14
15
shape.popup();

this.name в строке 7 будет явно пустым, как показано в консоли браузера:

Мы можем легко исправить эту проблему, используя стрелочную функцию TypeScript. Просто замените function() на ()=>.

1
var shape = {
2
	name: "rectangle",
3
	popup: function() {
4
5
		console.log('This inside popup(): ' + this.name);
6
7
		setTimeout( () => {
8
			console.log('This inside setTimeout(): ' + this.name);
9
			console.log("I'm a " + this.name + "!");
10
		}, 3000);
11
12
	}
13
};
14
15
shape.popup();

И результаты:

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


Классы с общедоступными и частными модификаторами доступа

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

1
class Shape {
2
3
	area: number;
4
	color: string;
5
6
	constructor ( name: string, width: number, height: number ) {
7
		this.area = width * height;
8
		this.color = "pink";
9
	};
10
11
	shoutout() {
12
		return "I'm " + this.color + " " + this.name +  " with an area of " + this.area + " cm squared.";
13
	}
14
}
15
16
var square = new Shape("square", 30, 30);
17
18
console.log( square.shoutout() );
19
console.log( 'Area of Shape: ' + square.area );
20
console.log( 'Name of Shape: ' + square.name );
21
console.log( 'Color of Shape: ' + square.color );
22
console.log( 'Width of Shape: ' + square.width );
23
console.log( 'Height of Shape: ' + square.height );

Вышеуказанный класс Shape имеет два свойства, area и color, один конструктор (точно названный constructor()), а также метод shoutout(). Скоуп аргументов конструктора (name, width и height) являются локальными для конструктора. Вот почему вы увидите ошибки в браузере, а также компилятора:

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

Любая программа JavaScript уже является программой TypeScript.

Затем давайте рассмотрим public и private модификаторы доступа. Доступ к публичным членам можно получить повсюду, тогда как частные члены доступны только в рамках класса. Разумеется, в JavaScript нет возможности для обеспечения конфиденциальности, поэтому доступность для частного доступа обеспечивается только во время компиляции и служит предупреждением первоначальному намерению разработчика сделать его конфиденциальным.

В качестве иллюстрации добавим модификатор public  к аргументу конструктора, name и модификатор private к color. Когда мы добавляем public или private доступность к аргументу конструктора, этот аргумент автоматически становится членом класса с соответствующим модификатором доступности.

1
...
2
private color: string;
3
...
4
constructor ( public name: string, width: number, height: number ) {
5
...
1
class.ts(24,41): The property 'color' does not exist on value of type 'Shape'

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

Наконец, вы можете расширить существующий класс и создать из него производный класс с ключевым словом extends. Давайте добавим следующий код к существующему файлу class.ts и скомпилируем его:

1
class Shape3D extends Shape {
2
3
	volume: number;
4
5
	constructor ( public name: string, width: number, height: number, length: number ) {
6
		super( name, width, height );
7
		this.volume = length * this.area;
8
	};
9
10
	shoutout() {
11
		return "I'm " + this.name +  " with a volume of " + this.volume + " cm cube.";
12
	}
13
14
	superShout() {
15
		return super.shoutout();
16
	}
17
}
18
19
var cube = new Shape3D("cube", 30, 30, 30);
20
console.log( cube.shoutout() );
21
console.log( cube.superShout() );

Несколько вещей происходят с производным классом Shape3D:

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


      Ресурсы TypeScript

      Несмотря на чрезвычайно молодой возраст TypeScript, вы можете найти много полезных ресурсов в Интернете (включая полный курс, который подходит к Tuts + Premium!). Обязательно проверьте их:


      Мы только начинаем

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

      Попробовать TypeScript легко. Если вам нравится более статически типизированный подход для больших приложений, то функции TypeScript будут применять привычную, дисциплинированную среду. Хотя его и сравнивают с CoffeeScript или Dart, TypeScript отличается тем, что он не заменяет JavaScript; он добавляет функции JavaScript.

      Нам еще предстоит увидеть, как будет развиваться TypeScript, но Microsoft заявила, что сохранит свои многочисленные функции (аннотации типов) в соответствии с ECMAScript 6. Итак, если вы хотите попробовать многие новые функции ES6, TypeScript - отличный способ сделать это! Вперед, попробуйте!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.