Тогда массив может быть пустым или содержать n
элементов.
Обычной задачей является проверка того, пуст ли массив для работы с ним. Как определить, что массив пуст?
В Javascript эта задача выполняется с помощью условного блока и проверки свойства .length
массива.
Но можно ли использовать язык ввода Typescript, чтобы массив не был пустым без использования условного оператора?
Идея здесь состоит в том, чтобы позволить Typescript проверять поток данных и выдавать нам ошибку, если вы пытаетесь получить доступ к пустому массиву.
Что вы сделаете, так это создадите новый тип, похожий на Array
, который позволит вам определить массив, который не может быть пустым по определению.
Назовем этот тип NonEmptyArray
.
type NonEmptyArray<T> = [T, ...T[]]
const emptyArr: NonEmptyArray<Item> = [] // error ❌
const emptyArr2: Array<Item> = [] // ok ✅
function expectNonEmptyArray(arr: NonEmptyArray<unknown>) {
console.log('non empty array', arr)
}
expectNonEmptyArray([]) // you cannot pass an empty array. ❌
expectNonEmptyArray(['som valuue']) // ok ✅
So whenever you require, for example, a function parameter to be an array that cannot be empty, you can use NonEmptyArray
.
Единственным недостатком является то, что теперь вам потребуется функция «защиты типов», поскольку простая проверка того, что свойство length
массива не равно 0, не преобразует его в тип NonEmptyArray
.
function getArr(arr: NonEmptyArray<string>) {
return arr;
}
const arr3 = ['1']
if (arr3.length > 0)) {
// ⛔️ Error: Argument of type 'string[]' is not
// assignable to parameter of type 'NonEmptyArr<string>'.
getArr(arr3);
}
Эта ошибка возникает из-за того, что getArr
ожидает, что аргумент будет NonEmptyArray
, но arr3
имеет тип Array
.
Тип охранников
Функция «защиты типа» позволяет вам «помочь» Typescript правильно определить тип некоторой переменной.
Это простая функция, которая возвращает логическое значение. Если это значение равно true
, то Typescript будет считать, что оцениваемая переменная относится к тому или иному типу.
// Type Guard
function isNonEmpty<A>(arr: Array<A>): arr is NonEmptyArray<A>{
return arr.length > 0
}
Эта функция получает общий массив (отсюда и использование A
) и проверяет, больше ли свойство length
, чем 0
.
Эта функция помечена как возвращающая arr is NonEmptyArray<A>
, т. е. значение оцениваемого условия равно true
. Typescript поймет, что используемый параметр arr
имеет тип NonEmptyArray
.
// Type Guard
function isNonEmpty<A>(arr: Array<A>): arr is NonEmptyArray<A>{
return arr.length > 0
}
function getArr(arr: NonEmptyArray<string>) {
return arr;
}
const arr3 = ['1']
// ^? const arr3: string[]
if (isNonEmpty(arr3)) {
getArr(arr3);
// ^? const arr3: NonEmptyArray<string>
}
Простой способ понять защиту типа состоит в том, что вы «приводите» один тип к другому типу тогда и только тогда, когда выполняется определенное условие. Что делает это преобразование безопасным по сравнению с простым приведением типов as NonEmptyArray
Ознакомьтесь с игровой площадкой машинописи с этими примерами.