TypeScript определяет несколько специальных типов, имеющих особое поведение в системе типов.
Эти типы используются в различных ситуациях для обработки случаев, когда тип заранее неизвестен или когда необходимо работать с примитивами JavaScript безопасным образом.
Примечание: Эти специальные типы являются частью системы типов TypeScript и помогают сделать ваш код более защищённым от ошибок и самодокументируемым.
Тип: any
Тип any — самый гибкий тип в TypeScript.
Фактически, он приказывает компилятору пропустить проверку типов для определенной переменной.
Хотя это может быть полезно в некоторых ситуациях, использовать его следует умеренно, так как он отменяет функции обеспечения безопасности типов в TypeScript.
Когда использовать any:
- При переносе кода JavaScript в TypeScript.
- При работе с динамическим контентом, где тип неизвестен.
- Когда нужно отключить проверку типов для отдельного случая.
В следующем примере не используется тип any, и будет выброшена ошибка:
Пример без использования типа any
let u = true;
u = "string"; // Ошибка: Тип 'string' не может быть назначен типу 'boolean'.
Math.round(u); // Ошибка: Аргумент типа 'boolean' не может быть назначен параметру типа 'number'.
Установка переменной в особый тип any отключает проверку типов:
Пример с использованием типа any
let v: any = true;
v = "string"; // Без ошибки, так как может быть любым типом
Math.round(v); // Без ошибки, так как может быть любым типом
Тип any полезен для преодоления ошибок, так как отключает проверку типов, но TypeScript не сможет обеспечить безопасность типов, и инструменты, полагающиеся на данные о типах (такие как автодополнение), перестанут работать.
Этого следует избегать любой ценой.
Тип: unknown
Тип unknown — это безопасный аналог типа any.
Это безопасный способ сказать "этот тип может быть чем угодно, но вы обязаны предварительно выполнить некоторую проверку перед его использованием".
Ключевые различия между unknown и any:
unknownдолжен пройти проверку типа перед использованием.- Нельзя обращаться к свойствам типа
unknownбез утверждения типа. - Нельзя вызывать или конструировать значения типа
unknown.
TypeScript предотвратит использование типов unknown без надлежащей проверки типа, как показано в следующем примере:
Пример
let w: unknown = 1;
w = "string"; // Без ошибки
w = {
runANonExistentMethod: () => {
console.log("Я мыслю, следовательно существую");
}
} as { runANonExistentMethod: () => void };
// Как избежать ошибки, если мы не знаем тип?
// w.runANonExistentMethod(); // Ошибка: Объект типа 'unknown'.
if (typeof w === 'object' && w !== null) {
(w as { runANonExistentMethod: Function }).runANonExistentMethod();
}
Хоть нам пришлось несколько раз приводить к типу, мы смогли провести проверку в условии if, чтобы обезопасить наше утверждение и добиться более безопасного приведения типа.
Когда использовать unknown:
- При работе с данными из внешних источников (API, пользовательский ввод и т.д.).
- Когда нужно обеспечить безопасность типов, оставаясь при этом гибкими.
- При переходе от JavaScript к TypeScript безопасным способом.
Сужение типов с unknown:
Вы можете сузить тип значения unknown с помощью проверки типа:
Пример
function processValue(value: unknown) {
if (typeof value === 'string') {
// value теперь рассматривается как string
console.log(value.toUpperCase());
} else if (Array.isArray(value)) {
// value теперь рассматривается как any[]
console.log(value.length);
}
}
Тип: never
Тип never представляет тип значений, которые никогда не возникают.
Он используется для обозначения того, что нечто никогда не произойдёт или не должно происходить.
Общие сценарии использования never:
- Функции без возврата (всегда генерируют ошибку или входят в бесконечный цикл).
- Проверки типов, которые никогда не пройдут проверку типа.
- Проверка полноты для дискриминантных объединений.
Примеры использования never:
1. Функция без возврата
function throwError(message: string): never {
throw new Error(message);
}
2. Проверка полноты для дискриминантных объединений
type Shape =
| { type: "circle"; radius: number }
| { type: "square"; side: number }
| { type: "triangle"; base: number; height: number };
function getArea(shape: Shape): number {
switch (shape.type) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.side ** 2;
case "triangle":
return (shape.base * shape.height) / 2;
default:
// Компилятор выдаст ошибку, если какой‑то case пропущен
const _exhaustiveCheck: never = shape;
throw new Error(`Неизвестный тип фигуры: ${shape.type}`);
}
}
3. Базовый тип never (вызывает ошибку при назначении)
let x: never = true; // Ошибка: Тип 'boolean' не может быть назначен типу 'never'.
Когда использовать тип never:
- Для функций, которые никогда не возвратят значение.
- В проверках типов, которые никогда не смогут соответствовать.
- Для исчерпывающей проверки типов в конструкциях
switch. - В обобщённых типах для указания невозможных случаев.
Типы: undefined и null
В TypeScript значения undefined и null имеют свои собственные типы, подобно типам string или number.
По умолчанию эти значения могут быть назначены любому другому типу, но это можно изменить, включив строгие проверки null в TypeScript.
Ключевые моменты о undefined и null:
undefinedозначает, что переменная объявлена, но ей не присвоено значение.null— это явное назначение, представляющее отсутствие значения или объекта.- В TypeScript оба значения имеют свои собственные типы:
undefinedиnullсоответственно. - При включении строгих проверок null (strictNullChecks) вы должны явно обрабатывать эти типы.
Базовое использование:
let y: undefined = undefined;
let z: null = null;
Необязательные параметры и свойства:
// Необязательный параметр (неявно `string | undefined`)
function greet(name?: string) {
return `Привет, ${name || 'незнакомец'}`;
}
// Необязательное свойство в интерфейсе
interface User {
name: string;
age?: number; // То же самое, что `number | undefined`
}
Ниллинговое слияние и необязательная цепочка:
Ниллинговое слияние (??): использует значение по умолчанию только в том случае, если исходное значение равно null или undefined.
const value = input ?? 'default';
Необязательная цепочка (?.): безопасно обращается к вложенным свойствам.
const street = user?.address?.street;
Важно: Эти типы наиболее полезны, когда включена опция strictNullChecks в файле tsconfig.json.
Это гарантирует, что значения null и undefined могут быть присвоены только соответствующему типу и типу any.
Чтобы включить строгие проверки null, добавьте в ваш файл tsconfig.json следующие строки:
{
"compilerOptions": {
"strictNullChecks": true
}
}