Сужение типов
“Что это за монстр такой?” — спросите Вы, сейчас я попробую Вам ответить на этот вопрос
Примеры
Примечание:
Сужать типы можно с помощью typeof, instanceof, Array.isArray, isNaN:
typeof
Возможные варианты typeof
stringnumberbigintbooleansymbolundefinedobjectfunction
Давайте представим, что у нас есть функция, которая может принимать
const = (: string | string[]) => { /* empty */ };Окей, хорошо! Теперь нам нужно как-то определить, что нам поступает, строка или массив.
Мы можем сделать это через typeof, который определяет тип (но с небольшим но)
const = (: string | string[]) => {
if (typeof === "string") {
return ;
} else {
const = .("\n");
return ;
}
}Ну или можем сделать попроще:
const = (: string | string[]) => {
const = typeof === "string"
?
: .("\n");
return ;
};Что здесь в итоге происходит? На деле всё просто: мы ограничиваем исходный тип какими-то другими. Разберем нашу функцию:
она принимает data с типом string|string[], а значит мы не можем знать наверняка, какой тип нам придёт, однако нам нужно как-то это узнать
тут-то и помогает сужение типов: мы сами определяем, с каким типом мы хотим работать
instanceof
type = string | string[] | Error;
const = (: ): string => {
if ( instanceof ) {
return . ?? .;
} else if (typeof === "string") {
return
} else {
return .("\n");
}
}Как работает instanceof? Он работает только с объектами (не с типами), для этого он и нужен — typeof работает только для встроенных типов
(см. возможные варианты typeof)
С помощью instanceof мы можем определить свои объекты, которые можем использовать для определения типа данного нам объекта
Array.isArray
type <> = | [, ...[]];
const = <>(: <>): {
: [],
: number,
: string
} => {
if (.()) {
return {
: ,
: .,
: "Получен массив"
};
} else {
return {
: [],
: 1,
: "Получен одиночный элемент"
};
}
};Array.isArray помогает нам понять, дали ли нам массив или нет, так как typeof определять массив как object.
Тут, думаю, больше нечего рассказывать
isNaN
type = string | number;
const = ({ , , }: { : , : , : string }): string => {
const = +;
const = +;
const = () || ()
if () {
throw new ("Цена и количество должны быть числами");
};
const = <= 0 || <= 0;
if () {
throw new ("Цена и количество должны быть положительными");
};
const = * ;
const = `Общая стоимость: ${.(2)} ${}.`;
return ;
};isNaN просто проверяет, не является ли число не числом (если мы перевели строку в число, то оно может быть NaN, но NaN относиться к типу number)
Небольшое НО:
Как Вы заметили, здесь нет типа array, потому что он помечается как object. Чтобы узнать достоверно,
является ли сущность массивом, нужно исопльзовать встроенные метод в JavaScript: Array.isArray
Он вернёт true, если сущность является массивом, иначе false
console.log(Array.isArray(["1", "2"])) // true
console.log(Array.isArray(null)) // false
console.log(Array.isArray(undefined)) // false
console.log(Array.isArray({ hello: [] })) // false
console.log(Array.isArray("str")) // false