=====Базовые типы=====
===== Введение # =====
Typescript является языком со статической типизацией. Тип не может быть изменен в ходе выполнения программы. Это позволяет снизить большое количество ошибок и выявить многие из них еще на этапе компиляции.
В Typescript есть несколько простых типов данных: numbers (числа), strings (строки), structures (структуры), boolean (логический). Он поддерживает все типы, которые есть в Javascript, дополняя удобным типом перечислений (enum).
===== Boolean # =====
Наиболее базовым типом является логический ture/false, который в Javascript и Typescript называется boolean.
let isDone: boolean = false;
===== Number # =====
Как и в Javascript, тип numbers в Typescript являются числом с плавающей точкой. Кроме десятичного и шестнадцатиричного формата, поддерживаются бинарный и восьмеричный, введенные в ECMAScript 2015.
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
===== String # =====
Еще одна важная часть программ в веб-страницах и серверах это текстовые данные. Как и в других языках, в Typescript используется то же обозначение "string" для таких данных. Как и Javascript, в Typescript используются двойные (''"'') или одинарные (''''') кавычки для обрамления текстовых данных.
let name: string = "bob";
name = 'smith';
Вы также можете использовать строки с шаблонами, которые могут быть многострочными и иметь встроенные выражения. Эти строки окружаются обратными апострофами или кавычками(''`'') и встроенные выражения обозначаются как ''${ expr }''.
let name: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ name }.
I'll be ${ age + 1 } years old next month.`
Эквивалент этого объявления ''sentence'':
let sentence: string = "Hello, my name is " + name + ".\n\n" +
"I'll be " + (age + 1) + " years old next month."
===== Array # =====
TypeScript, как и JavaScript, имеет массивы значений. Тип массива может быть определен одним из двух способов. Первый - обозначать тип элементов массива перед ''[]'':
let list: number[] = [1, 2, 3];
Второй способ - использовать обобщение ''Array'':
let list: Array = [1, 2, 3];
===== Tuple # =====
Тип Tuple дает вам возможность объявить массив с известным фиксированным количеством элементов, которые не обязаны быть одного типа. Например, вы хотите иметь значение Tuple как пару "строка" и "число":
// Объявление типа tuple
let x: [string, number];
// Его инициализация
x = ['hello', 10]; // OK
// Некорректная инициализация вызовет ошибку
x = [10, 'hello']; // Error
Когда вы получаете элемент с известным идексом, будет возвращен тип этого элемента:
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'
При получении элемента с идексом вне известного диапазона, будет возвращен тип Union:
x[3] = 'world'; // OK, тип string может быть присвоен (string | number)
console.log(x[5].toString()); // OK, 'string' и 'number' оба имеют метод toString
x[6] = true; // Ошибка, boolean это не (string | number)
Тип Union будет описан чуть позже, в разделе продвинутых типов.
===== Enum (Перечисления) # =====
Полезным дополнением к стандартному набору типов из Javascript является тип Enum. Как и в языках подобных C#, тип enum - это более удобный способ задания понятных имен набору численных значений.
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
По умолчанию перечисления (Enum) начинаются с ''0''. Вы можете изменить это путем прямого указания значения для одного из членов перечисления. Например, мы можем начать предыдущий пример с ''1'' вместо ''0'':
enum Color {Red = 1, Green, Blue};
let c: Color = Color.Green;
Или даже задать значения для всех членов:
enum Color {Red = 1, Green = 2, Blue = 4};
let c: Color = Color.Green;
Удобная особенность перечислений состоит в том, что вы также можете получить имя члена перечисления, передав его числовое значение. Например, если у нас есть значение ''2'' и мы хотим посмотреть, чему оно соответствует в перечислении ''Color'' описанном выше, мы можем сделать это так:
enum Color {Red = 1, Green, Blue};
let colorName: string = Color[2];
alert(colorName);
===== Any # =====
Нам может потребоваться описать тип переменных, который мы не знаем, когда пишем наше приложение. Эти значения могут быть получены из динамического контента, например от пользователя или от сторонней библиотеки. В этих случаях мы хотим отключить проверку типов и позволить значениям пройти проверку на этапе компиляции. Чтобы это сделать, нужно использовать тип ''any'':
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // ok, это определенно boolean
Тип ''any'' - это мощный способ работы с существующим Javascript, который позволяет вам постепенно включать все больше проверок типов на этапе компиляции. Вы можете ожидать, что ''Object'' будет играть такую же роль, какую и в других языках. Но переменные типа ''Object'' позволяют вам только присваивать им любое значение. Вы не можете вызывать у них необъявленные методы, даже те, которые могут существовать на этапе исполнения программы:
let notSure: any = 4;
notSure.ifItExists(); // ifItExists может существовать на этапе исполнения
notSure.toFixed(); // метод toFixed существует (но компилятор не проверяет это)
let prettySure: Object = 4;
prettySure.toFixed(); // Ошибка: Свойство 'toFixed' не существует у типа 'Object'.
Тип ''any'' может быть также полезен, если вы знаете некоторую часть типа переменной, но не весь. Например, у вас может быть массив с элементами различных типов:
let list: any[] = [1, true, "free"];
list[1] = 100;
===== Void # =====
''void'' это нечто противоположное ''any'': отсутствие каких-либо типов. Чаще всего он используется в качестве возвращаемого типа функций, которые не возвращают никакого значения.
function warnUser(): void {
alert("This is my warning message");
}
Объявление переменных с типом ''void'' бесполезно, потому что вы можете присвоить им только значения ''undefined'' или ''null'':
let unusable: void = undefined;
====== Type assertions (Приведение к типу) # ======
Иногда вы попадаете в ситуацию, когда знаете больше о значении переменной, чем Typescript. Обычно это случается, когда вы знаете, что тип некоторой сущности может быть более специфичным, чем ее текущий.
Type assertions - это способ сказать компилятору "поверь мне, я знаю, что делаю". Type assertion это как приведение к типу в других языках, но оно не делает никаких специальных проверок или реструктуризаций данных. Приведение к типу не имеет никакого воздействия на этапе выполнения программы и используется только компилятором. Typescript предполагает, что программист сделает все необходимые проверки, которые потребуются.
Приведение к типу может быть сделано двумя способами. Первый это использование синтаксиса угловых скобок:
let someValue: any = "this is a string";
let strLength: number = (someValue).length;
И другой - использование ключевого слова ''as'':
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
Эти два примера эквивалентны. Использование одного из них это просто выбор более предпочтительного варианта; тем не менее, когда вы используете Typescript с JSX, возможно только приведение к типу через ''as''.
===== Немного о let # =====
Вы могли заметить, что недавно было введено новое ключевое слово ''let'' вместо ''var'' из JavaScript, с которым вы знакомы. Ключевое слово ''let'' - это просто новый способ задания переменной в JavaScript, который уже доступен в Typescript. Мы обсудим детали позже, сейчас же просто знайте, что много проблем в Javascript можно избежать, используя ''let''. Поэтому вы должны использовать его вместо ''var'', где это возможно.