编程全栈开发者

在 TypeScript 中,数组的类型如何定义,如何正确声明具有不同类型元素的数组,并且有哪些方法可以使用元组 (tuples) 来描述它们?请举例并解释与这些结构相关的可能错误。

用 Hintsage AI 助手通过面试

答案。

在 TypeScript 中,数组主要通过两种方式进行描述:类型[]Array<类型>。对于具有不同类型元素的数组,使用联合类型 (union types) 或元组 (tuples),后者可以描述固定数量的不同类型的元素。

数组声明:

let numbers: number[] = [1, 2, 3]; let strings: Array<string> = ['a', 'b', 'c'];

具有不同类型元素的数组:

let mixed: (string | number)[] = [1, 'a', 2];

元组 (tuples):

let tuple: [string, number, boolean] = ['hello', 42, true];

当预期结构是固定的(例如,函数返回多个不同类型的值时)时,使用元组更方便,而数组则适用于元素数量和类型可以混合或不确定的情况。

陷阱问题。

在定义长度为 N 的元组之后,是否可以通过 push 方法向其添加元素?这对类型系统有什么影响?

答案: 是的,可以向元组中推送元素——编译器允许这样做,尽管这违反了元组长度的有限性假设。新元素的类型将被转换为元组中所有可能类型的联合:

let tuple: [number, string] = [42, 'foo']; tuple.push(true); // OK! 现在的元组: [number, string, boolean],但类型没有更新,没有错误! console.log(tuple); // [42, 'foo', true]

因此,需要手动控制对元组的操作和它们的可变性,或者将它们设置为只读。

由于不了解该主题的细微差别而导致的真实错误示例。


故事

开发者描述了一个返回元组 [number, string] 的函数,但后来开始通过 push 向结果中添加元素。这导致了类型的不匹配:后续代码期待正好两个特定类型的元素,但得到了一个可变长度的数组,因而在解包值和访问不存在的索引时产生了运行时错误。


故事

为存储不同类型值的数组使用了 any[] 数组,认为这是一种通用解决方案。结果 TypeScript 停止检查类型的正确性,应用程序逻辑由于类型错误的转换开始出错,这些转换并未引发编译错误。


故事

在项目中,数组要么通过类型[] 要么通过 Array<类型> 进行描述——但在某些地方允许使用 let arr: any[](以便可以处理任何内容)。因此出现了无法控制的转换,任何数组都会接受这个函数,导致在尝试对不同类型元素调用不正确的方法时出现运行时错误。