TypeScript — это надмножество JavaScript, то есть, любой код на JS является правильным с точки зрения TypeScript. Однако, TypeScript обладает некоторыми дополнительными возможностями, которые не входят в JavaScript. Среди них — строгая типизация (то есть, указание типа переменной при её объявлении, что позволяет сделать поведение кода более предсказуемым и упростить отладку), механизмы объектно-ориентированного программирования и многое другое. Браузеры не поддерживают TypeScript напрямую, поэтому код на TS надо транспилировать в JavaScript.
TypeScript поддерживает различные типы данных. Среди них можно отметить следующие:
let a: number //например: 1, 2, 3
let b: boolean //например: true, false
let c: string //например: "abel agoi"
let d: any //такая переменная может содержать значения любых других типов
let e: number[] //числовой массив, например: [1, 3, 54]
let f: any[] //массив значений любых типов, например: [1, "abel agoi", true]
let log = (message) => { //тут мы просто убираем слово function
console.dir(message);
}
interface MyParameters {
a: number,
b: number,
c: string,
d: any,
e: number[],
f: any[]
...
...
}
let myFunction = (myParameters: MyParameters) {
}
Группировка связанных переменных(свойства) и функций(методы) в единую конструкцию, которая в программировании называется классом.
class MyPoint {
x: number;
y: string;
draw() {
//обратите внимание на то, что со свойством x мы работаем через this
console.log("X is: " + this.x);
console.log("X is: " + this.y);
}
getDistanceBtw(another: AnotherPoint) {
//посчитать и вернуть расстояние
}
}
Мы сгруппировали связанные переменные и методы в единый класс. Теперь надо разобраться с тем, как с ними работать. Для этого нужно создать экземпляр класса:
let myPoint = new MyPoint() //MyPoint - это имя класса
myPoint.x = 2; //устанавливаем свойство x
myPoint.y = "a"; //устанавливаем свойство y
myPoint.draw(); //вызываем метод draw
Конструктор — это метод, который вызывается автоматически при создании экземпляров класса. Конструктор позволяет задавать значения свойств. Вот пример работы с экземпляром класса, в котором возможности конструкторов не применяются:
Однако, для того, чтобы вышеприведённый пример заработал, понадобится внести изменения в класс, задав его конструктор:
class MyPoint {
x: number;
y: string;
constructor (x: number, y: string) {
this.x = x;
this.y = y;
}
draw() {
//обратите внимание на то, что со свойством x мы работаем через this
console.log("X is: " + this.x);
console.log("X is: " + this.y);
}
getDistanceBtw(another: AnotherPoint) {
//посчитать и вернуть расстояние
}
}
Предположим, что сейчас класс MyPoint выглядит так:
class MyPoint {
constructor (private x?: number, private y?: string) {}
draw() {
//нарисовать что-нибудь
}
drawAnotherThing() {
//нарисовать ещё что-нибудь
}
}
Мы совершенно точно знаем, что не сможем работать со свойствами x и y за пределами экземпляра класса MyPoint, так как они объявлены с использованием модификатора доступа private. Если же нужно как-то на них влиять или читать их значения извне, нам понадобится использовать геттеры (для чтения свойств) и сеттеры (для их модификации). Вот как это выглядит:
class Test {
private _testField: string = null;
get fieldName() : string {
return this._testField;
}
set fieldName(name : string) {
this._testField = name;
}
}
var test = new Test();
test.fieldName = "Hello World";
alert(test.fieldName);
Когда вы приступите к созданию реальных приложений, вы обнаружите, что в них понадобится далеко не один класс. Поэтому хорошо бы найти средство, позволяющее создавать классы так, чтобы их можно было использовать в других файлах, и в классах, объявленных в этих файлах, то есть, нам нужны инструменты написания модульного кода.
export class MyPoint { //обратите внимание на новое ключевое слово export
constructor (private _x?: number, private _y?: string) {}
get x() {
return this._x;
}
set x(value) { //обратите внимание на пробел перед x
this._x = value;
}
draw() {
//нарисуем что-нибудь
}
}
import { MyPoint } from './myPoint';
class Main {
let MyPoint = new MyPoint(4, "go to go");
MyPoint.draw();
}