在TypeScript中定义具有多个类型的数组

458
我有一个如下形式的数组:[ 1, "message" ]
我应该如何在TypeScript中定义它?

这是一个类似的问题,但没有答案。这次涉及到使用类继承,其中有未知数量的项,并且所有项都扩展自相同的类:https://stackoverflow.com/questions/50322488/array-of-unknown-size-with-items-of-different-classes-that-extends-the-same-pare - cancerbero
10个回答

784

在 TypeScript 中定义包含多种类型的数组

使用联合类型 (string|number)[] 示例:

const foo: (string|number)[] = [ 1, "message" ];

我有一个形如:[ 1, "message" ]的数组。
如果你确定这个数组总是只有两个元素 [number, string],那么你可以将它声明为一个元组:
const foo: [number, string] = [ 1, "message" ];

你甚至可以为元组成员提供有意义的名称,例如idtext

const foo: [id: number, text: string] = [ 1, "message" ];

3
需要TS v1.4或更高版本。 - Brocco
30
当你想访问仅存在于某个类型中的属性时,使用该方法无法处理具有不同属性的复杂类型。 - seawave_23
2
@Nadine 那种情况下,有什么可以做的吗? - msanford
11
每次当你清楚知道它是哪种类型时,你可以进行类型断言。然后就可以访问该类型的属性了。 - seawave_23
不错的观点@seawave_23,如果可能的话,我建议你编辑被接受的答案,加入这些信息。 - A. Khaled

110
如果您将其视为元组(请参见语言规范第3.3.3节),那么:
var t:[number, string] = [1, "message"]

或者

interface NumberStringTuple extends Array<string|number>{0:number; 1:string}
var t:NumberStringTuple = [1, "message"];

14
TIP: 我更喜欢使用 type NumberStringTuple = [number, string] - basarat
1
谢谢!我正需要这个: const W3COLORS: [[string, string, number, number]] = [ ["aliceblue", "#f0f8ff", 240, 248, 255], ... ]; - CoderPi
1
注意 - 数组中必须同时包含两种类型(对于空数组也不起作用)。接受的答案更加通用,我个人总是使用它,但这取决于需求。 - Druvis Cukurs

57

我的TS lint(代码检查工具)对于其他解决方案进行了投诉,所以对我有效的解决方案是:

item: Array<Type1 | Type2>

如果只有一种类型,使用如下即可:

item: Type1[]

这很好,但是如果我们现在正在循环遍历数组,我们如何确定当前数组的类型? - dessalines
2
在TypeScript中,如何为特定类型编写switch语句? - Rambatino

40

TypeScript 3.9+ 更新 (2020年5月12日)

现在,TypeScript 还支持命名元组。这极大地提高了代码的可理解性可维护性请查看官方 TS Playground。


所以,现在不再使用无名称:

const a: [number, string] = [ 1, "message" ];

我们可以添加名称:

const b: [id: number, message: string] = [ 1, "message" ];

注意:您需要一次性添加所有名称,不能省略某些名称,例如:

type tIncorrect = [id: number, string]; // INCORRECT, 2nd element has no name, compile-time error.
type tCorrect = [id: number, msg: string]; // CORRECT, all have a names.

提示:如果您不确定最后一个元素的数量,可以这样编写:

type t = [msg: string, ...indexes: number];// means first element is a message and there are unknown number of indexes.

TypeScript 4.x+ 可变元组类型

对于TS 4.x,最后一个示例必须更改为以下内容:

type t = [msg: string, ...indexes: number[]];// means first element is a message and there are unknown number of indexes.

类型number被改为number[]
更多信息请参见:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#variadic-tuple-types

1
它是用来干什么的?元组元素上的名称? - Marecky
2
@Marecky 这是为了方便使用而添加的,例如来自 TypeScript 编译器的提示:(property) 0: number (id) 而不是统一的 (property) 0: number。因此,如果有错误消息,它将提供更多细节。 - Oleg Zarevennyi

25

6

我正在使用这个版本:

exampleArr: Array<{ id: number, msg: string}> = [
   { id: 1, msg: 'message'},
   { id: 2, msg: 'message2'}
 ]

这个建议有点类似于其他建议,但仍然很简单,并且相当容易记住。


6

如果您希望获取数字或字符串数组,您可以定义一个类型,该类型将接受数字或字符串数组。

type Tuple = Array<number | string>
const example: Tuple = [1, "message"]
const example2: Tuple = ["message", 1]

如果你期望一个特定顺序的数组(例如数字和字符串)

type Tuple = [number, string]
const example: Tuple = [1, "message"]
const example2: Tuple = ["messsage", 1] // Type 'string' is not assignable to type 'number'.

4
const myarray:(TypeA | TypeB)[];

为了避免需要添加其他类型时在多个地方进行更改,最好创建类型。

type MyMixedType = TypeA | TypeB;
const myarray: MyMixedType[];

0
[ 1, "message" ] as const ;

如果你使用 "as const",类型将会是

type const = readonly [1, "message"]

由于计算机可能的精确类型推断,这是很好的。


0
如果处理一个包含多个值类型的对象数组,这个方法对我很有用。
 { [key: string]: number | string }[]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接