Тип данных в программировании — это классификация, которая указывает, какой тип значения содержит переменная и какие типы математических, реляционных или логических операций могут быть применены к ней, не вызывая ошибки.
логический
Самый простой тип данных — это простое значение true/false, которое JavaScript и TypeScript называют значением boolean.
let isDone: boolean = true; let isNotSelecetd: boolean = false;
Число
Как и в JavaScript, все числа в TypeScript представляют собой либо значения с плавающей запятой, либо BigInteger. Эти числа с плавающей запятой получают тип number, а BigIntegers получают тип bigint. Помимо шестнадцатеричных и десятичных литералов, TypeScript также поддерживает двоичные и восьмеричные литералы, представленные в ECMAScript 2015.
let decimal: number = 6; let hex: number = 0xf00d; let binary: number = 0b1010; let octal: number = 0o744; let big: bigint = 100n;
Нить
Еще одна фундаментальная часть создания программ на JavaScript как для веб-страниц, так и для серверов — это работа с текстовыми данными. Как и в других языках, мы используем тип string для обозначения этих текстовых типов данных. Как и JavaScript, TypeScript также использует двойные кавычки (") или одинарные кавычки (') для заключения строковых данных.
let color: string = "blue"; color = 'red';
Вы также можете использовать строки-шаблоны, которые могут занимать несколько строк и содержать встроенные выражения. Эти строки окружены символом обратной кавычки (`), а встроенные выражения имеют форму ${ expr }.
let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.
I'll be ${age + 1} years old next month.`;
Это эквивалентно объявлению sentence следующим образом:
let sentence: string = "Hello, my name is " + fullName + ".\n\n" + "I'll be " + (age + 1) + " years old next month.";
Множество
TypeScript, как и JavaScript, позволяет работать с массивами значений. Типы массивов могут быть записаны одним из двух способов. В первом вы используете тип элементов, за которым следует [], чтобы обозначить массив элементов этого типа:
let list: number[] = [1, 2, 3]; or let list: Array<number> = [1, 2, 3];
Кортеж
Типы кортежей позволяют вам выразить массив с фиксированным числом элементов, типы которых известны, но не обязательно должны быть одинаковыми. Например, вы можете захотеть представить значение в виде пары string и number:
// Declare a tuple type let x: [string, number]; // Initialize it x = ["hello", 10]; // OK // Initialize it incorrectly x = [10, "hello"]; // Error // OK console.log(x[0].substring(1)); // When accessing an element with a known index, the correct type is retrieved console.log(x[1].substring(1)); Property 'substring' does not exist on type 'number'. x[3] = "world"; Tuple type '[string, number]' of length '2' has no element at index '3'. console.log(x[5].toString()); Object is possibly 'undefined'. Tuple type '[string, number]' of length '2' has no element at index '5'.
перечисление
Полезным дополнением к стандартному набору типов данных из JavaScript является расширение enum. Как и в таких языках, как C#, перечисление — это способ дать более понятные имена наборам числовых значений.
enum Color {
Red,
Green,
Blue,
}
let c: Color = Color.Green;
По умолчанию перечисления начинают нумерацию своих элементов, начиная с 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];
// Displays 'Green'
console.log(colorName);
Неизвестный
Нам может понадобиться описать тип переменных, которые мы не знаем, когда пишем приложение. Эти значения могут исходить из динамического содержимого — например. от пользователя — или мы можем намеренно принять все значения в нашем API. В этих случаях мы хотим предоставить тип, который сообщает компилятору и будущим читателям, что эта переменная может быть чем угодно, поэтому мы присваиваем ей тип unknown.
let notSure: unknown = 4; notSure = "maybe a string instead"; // OK, definitely a boolean notSure = false;
Если у вас есть переменная с неизвестным типом, вы можете сузить ее до чего-то более конкретного, выполнив typeof проверок, проверок сравнения или более сложных средств защиты типов, которые будут обсуждаться в следующей главе:
declare const maybe: unknown;
// 'maybe' could be a string, object, boolean, undefined, or other types
const aNumber: number = maybe;
Type 'unknown' is not assignable to type 'number'.
if (maybe === true) {
// TypeScript knows that maybe is a boolean now
const aBoolean: boolean = maybe;
// So, it cannot be a string
const aString: string = maybe;
Type 'boolean' is not assignable to type 'string'.
}
if (typeof maybe === "string") {
// TypeScript knows that maybe is a string
const aString: string = maybe;
// So, it cannot be a boolean
const aBoolean: boolean = maybe;
Type 'string' is not assignable to type 'boolean'.
}
В некоторых ситуациях не вся информация о типе доступна или ее объявление потребует несоответствующих усилий. Это может произойти для значений из кода, который был написан без использования TypeScript или сторонней библиотеки. В этих случаях мы можем отказаться от проверки типов. Для этого мы помечаем эти значения типом any:
declare function getValue(key: string): any;
// OK, return value of 'getValue' is not checked
const str: string = getValue("myString");
Нулевой и неопределенный
void немного похоже на противоположность any: отсутствие вообще какого-либо типа. Вы можете часто видеть это как возвращаемый тип функций, которые не возвращают значение:
function warnUser(): void {
console.log("This is my warning message");
}
В TypeScript как undefined, так и null на самом деле имеют свои типы с именами undefined и null соответственно. Как и void, они не очень полезны сами по себе:
// Not much else we can assign to these variables! let u: undefined = undefined; let n: null = null;
По умолчанию null и undefined являются подтипами всех остальных типов. Это означает, что вы можете назначить null и undefined чему-то вроде number.
Однако при использовании флага strictNullChecks null и undefined можно присвоить только unknown, any и их соответствующим типам (одним исключением является то, что undefined также можно присвоить void). Это помогает избежать многих распространенных ошибок. В тех случаях, когда вы хотите передать либо string, либо null, либо undefined, вы можете использовать тип объединения string | null | undefined.
Никогда
Тип never представляет тип значений, которые никогда не встречаются. Например, never — это тип возвращаемого значения для функционального выражения или выражения стрелочной функции, которое всегда выдает исключение или никогда не возвращает значение. Переменные также приобретают тип never при сужении любыми охранниками типов, которые никогда не могут быть истинными.
Тип never является подтипом каждого типа и может быть присвоен каждому типу; однако ни один тип не является подтипом never или не может быть назначен ему (кроме самого never). Даже any нельзя присвоить never.
Некоторые примеры функций, возвращающих never:
// Function returning never must not have a reachable end point
function error(message: string): never {
throw new Error(message);
}
// Inferred return type is never
function fail() {
return error("Something failed");
}
// Function returning never must not have a reachable end point
function infiniteLoop(): never {
while (true) {}
}
Объект
object — это тип, представляющий непримитивный тип, то есть все, что не является number, string, boolean, bigint, symbol, null или undefined.
Тип object позволяет лучше представить такие API, как Object.create. Например:
declare function create(o: object | null): void;
// OK
create({ prop: 0 });
create(null);
create(undefined); // with `--strictNullChecks` flag enabled, undefined is not a subtype of null
Argument of type 'undefined' is not assignable to parameter of type 'object | null'.
create(42);
Argument of type 'number' is not assignable to parameter of type 'object'.
create("string");
Argument of type 'string' is not assignable to parameter of type 'object'.
create(false);
Argument of type 'boolean' is not assignable to parameter of type 'object'.