在 TypeScript 中声明一个非空数组

在 TypeScript 中声明一个非空数组

Declare a Non-empty Array in TypeScript

使用元组类型中的剩余元素在 TypeScript 中声明一个非空数组,例如let arr: [number, ...number[]] = [1]. 语法意味着数组包含的第一个元素是数字,但数组是开放式的并且可以包含更多元素。

索引.ts
// ✅ Use an inline type let arr: [number, ...number[]] = [1]; // ⛔️ Error: Source has 0 element(s) but target requires 1.ts(2322) arr = []; // ✅ Or use a type alias with a generic type NonEmptyArr<T> = [T, ...T[]]; let arr2: NonEmptyArr<string> = ['a']; arr2 = ['a', 'b']; // ✅ Works // ⛔️ Error: Source has 0 element(s) but // target requires 1.ts(2322) arr2 = [];

我们使用元组声明了一个非空数组
,其最小长度为
1

第一个示例展示了如何声明一个非空数组,其中第一个元素是 anumber并且可以包含零个或多个附加元素。

...number[]语法称为
元组类型中的 Rest 元素,
表示元组是开放式的,可以具有零个或多个指定类型的附加元素。

例如,[string, ...boolean[]]表示一个元组,其第一个元素后跟任意数量的元素。 string boolean

元组可以包含 1 个以上的元素,但如果您尝试将其重新声明为空数组,则会出现错误。

索引.ts
let arr: [number, ...number[]] = [1]; // ⛔️ Error: Source has 0 element(s) but target requires 1.ts(2322) arr = [];

元组类型用于表示具有固定数量元素的数组,这些元素的类型是已知的,但可以不同。

您还可以使用
类型别名
来键入非空数组。

索引.ts
type NonEmptyArr<T> = [T, ...T[]]; let arr2: NonEmptyArr<string> = ['a']; arr2 = ['a', 'b']; // ✅ Works // ⛔️ Error: Source has 0 element(s) but // target requires 1.ts(2322) arr2 = [];

NonEmptyArr类型是一个数组,至少包含1type 的元素
T,但可能有零个或多个 type 的附加元素T

在条件中使用这种类型别名可能会造成混淆:

索引.ts
type NonEmptyArr<T> = [T, ...T[]]; const arr3: string[] = ['a']; function getArr(arr: NonEmptyArr<string>) { return arr; } if (arr3.length > 0) { // ⛔️ Error: Argument of type 'string[]' is not // assignable to parameter of type 'NonEmptyArr<string>'. getArr(arr3); }

解决这个问题的最简单方法是使用
类型断言

索引.ts
type NonEmptyArr<T> = [T, ...T[]]; const arr3: string[] = ['a']; function getArr(arr: NonEmptyArr<string>) { return arr; } if (arr3.length > 0) { // ✅ Works getArr(arr3 as NonEmptyArr<string>); }
元组类型用于表示具有固定数量元素的数组,这些元素的类型是已知的,但可以不同。

话虽如此,元组由数组表示,您仍然可以调用该pop()方法从元组中删除元素。

索引.ts
const arr: [number, ...number[]] = [1]; arr.pop(); // ✅ OK console.log(arr); // 👉️ []

如果你想防止这种情况发生,你可以将元组声明为
readonly.

索引.ts
const arr: readonly [number, ...number[]] = [1]; // ⛔️ Error: Property 'pop' does not // exist on type 'readonly [number, ...number[]]'.ts(2339) arr.pop();

但这也意味着您无法更改元组元素的值或添加更多元素。

发表评论