Spec-Zone.ru › TypeScript 5.1

Основные типы

Эта страница руководства заменена, перейдите на новую страницу

Для того, чтобы программы были полезны, нам нужно уметь работать с некоторыми из самых простых единиц данных: числами, строками, структурами, булевыми значениями и тому подобным. В TypeScript поддерживаются те же типы, что и в JavaScript, с дополнительным типом перечисления, чтобы упростить работу.

Булево

Наиболее базовый тип данных — это простое значение true/false, которое JavaScript и TypeScript называют boolean значением.

let isDone: boolean = false;

Число

Как и в JavaScript, все числа в TypeScript — это либо значения с плавающей точкой, либо BigIntegers. Эти числа с плавающей точкой получают тип 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];

Второй способ использует обобщённый тип массива, Array<elemType>:

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));
 
console.log(x[1].substring(1));

Обращение к элементу за пределами набора известных индексов приводит к ошибке:

x[3] = "world";
 
console.log(x[5].toString());

Перечисление

Полезное дополнение к стандартному набору типов данных из 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;
 
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;
}
 
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;
}

Любой

В некоторых ситуациях вся информация о типе не доступна или её объявление потребует ненадлежащих усилий. Это может произойти для значений из кода, написанного без TypeScript или сторонней библиотеки. В таких случаях мы можем отказаться от проверки типов. Для этого мы помечаем эти значения типом any:

declare function getValue(key: string): any;
// OK, return value of 'getValue' is not checked
const str: string = getValue("myString");

Тип any — мощный способ работы с существующим JavaScript, позволяющий постепенно включать и отключать проверку типов во время компиляции.

В отличие от unknown, переменные типа any позволяют получать доступ к произвольным свойствам, даже к тем, которые не существуют. Эти свойства включают функции, и TypeScript не будет проверять их существование или тип:

let looselyTyped: any = 4;
// OK, ifItExists might exist at runtime
looselyTyped.ifItExists();
// OK, toFixed exists (but the compiler doesn't check)
looselyTyped.toFixed();
 
let strictlyTyped: unknown = 4;
strictlyTyped.toFixed();

Тип any будет продолжать распространяться через ваши объекты:

let looselyTyped: any = {};
let d = looselyTyped.a.b.c.d;

В конце концов, помните, что вся удобство any достигается за счёт потери безопасности типов. Безопасность типов — одна из основных мотиваций использования TypeScript, и вы должны стараться избегать использования any когда это не нужно.

Пусто

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

function warnUser(): void {
  console.log("This is my warning message");
}

Объявление переменных типа void бесполезно, потому что им можно назначить только null (только если strictNullChecks не указан, см. следующий раздел) или undefined:

let unusable: void = undefined;
// OK if `--strictNullChecks` is not given
unusable = null;

Null и Undefined

В 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.

Типы объединений — это продвинутая тема, которую мы рассмотрим в последующей главе.

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

Никогда

Тип 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
 
create(42);
create("string");
create(false);

В целом, вам не нужно будет использовать это.

Утверждения типов

Иногда вы попадаете в ситуацию, когда знаете больше о значении, чем TypeScript. Обычно это происходит, когда вы знаете, что тип некоторого объекта может быть более специфичным, чем его текущий тип.

Утверждения типов — это способ сказать компилятору «поверьте мне, я знаю, что делаю». Утверждение типа похоже на приведение типов в других языках, но оно не выполняет никаких специальных проверок или реструктуризации данных. Оно не оказывает никакого влияния на выполнение и используется исключительно компилятором. TypeScript предполагает, что вы, программист, выполнили все необходимые проверки.

Утверждения типов имеют две формы.

Одна — синтаксис as:

let someValue: unknown = "this is a string";
 
let strLength: number = (someValue as string).length;

Другая версия — синтаксис «скобок-уголков»:

let someValue: unknown = "this is a string";
 
let strLength: number = (<string>someValue).length;

Два примера эквивалентны. Использование одного вместо другого в основном зависит от предпочтений; однако при использовании TypeScript с JSX разрешены только утверждения стиля as.

Примечание об let

Вы могли заметить, что до сих пор мы использовали ключевое слово let вместо ключевого слова JavaScript var, с которым вы, возможно, более знакомы. Ключевое слово let — это фактически более новая конструкция JavaScript, доступная в TypeScript. Вы можете прочитать в справочнике по руководству на странице Объявления переменных, как let и const исправляют многие проблемы с var.

О Number, String, Boolean, Symbol и Object

Может быть заманчиво считать, что типы Number, String, Boolean, Symbol или Object такие же, как и строчные версии, рекомендованные выше. Однако эти типы не относятся к языковым примитивам и почти никогда не должны использоваться как тип.

function reverse(s: String): String {
  return s.split("").reverse().join("");
}
 
reverse("hello world");

Вместо этого используйте типы number, string, boolean, object и symbol.

function reverse(s: string): string {
  return s.split("").reverse().join("");
}
 
reverse("hello world");

© 2012-2023 Microsoft
Licensed under the Apache License, Version 2.0.
https://www.typescriptlang.org/docs/handbook/basic-types.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API