TypeScript 对象数组:为厌倦错误者准备的逐步教程
您是否曾经在编写 TypeScript 时,试图向数组添加对象,却突然看到 IDE 出现红色下划线?很熟悉,对吧?问题 "How can I define an array of objects?" 是 Stack Overflow 上最热门的问题之一。这并非没有原因:没有正确的对象数组类型化,您的代码就会变成错误的源头和令人头疼的问题。
在本教程中,我们将探讨在 TypeScript 中定义对象数组的所有方法——从简单到高级。您将学习如何避免常见错误,如何使用接口,以及如何让您的代码不仅可用,而且美观。开始吧!
为什么简单的 [] 不起作用?
假设您编写了:
let users = [];TypeScript 将其视为 never[]——一个永远不应包含任何元素的数组。尝试向其中添加一个对象:
users.push({ name: '安娜', age: 25 }); // 错误!IDE 会报错:"Argument of type '{ name: string; age: number; }' is not assignable to parameter of type 'never'." TypeScript 不知道您要在数组中存储什么,因此它会阻止任何添加操作。
解决方案——显式指定数组类型。让我们来探讨所有选项。
方法 1:基本类型注解——方括号
最简单直观的方法是使用 类型[] 语法:
let users: { name: string; age: number }[] = [];
users.push({ name: '安娜', age: 25 }); // ✅ 有效users.push({ name: '伊万', age: 30 }); // ✅ 有效这里我们告诉 TypeScript:"嘿,这是一个对象数组,每个对象都有 name(字符串)和 age(数字)属性"。现在 IDE 满意了,自动补全功能正常,类型错误在编译阶段就被捕获。
缺点:如果对象结构复杂,直接在注解中描述会变得冗长。对于这种情况,我们发明了接口。
方法 2:接口——您最好的朋友
接口允许将对象描述提取为单独的实体并重复使用。这使代码更清晰、更易理解:
interface User { id: number; name: string; age: number; email?: string; // 可选属性}
let users: User[] = [];
users.push({ id: 1, name: '安娜', age: 25 });users.push({ id: 2, name: '伊万', age: 30, email: 'ivan@example.com' }); // ✅现在,如果您尝试添加一个没有 id 字段或类型不正确的对象,TypeScript 会报错。当同一对象类型在多个地方使用时,接口尤其有用。
那 type 呢?
您可以使用 type 代替 interface:
type User = { id: number; name: string; age: number;};
let users: User[] = [];interface 和 type 之间的区别是另一篇文章的主题。对于对象数组,两种方式都可以使用,但 interface 更常用于描述对象形状。
方法 3:泛型语法 Array<Type>
另一种方法是使用泛型:
let users: Array<{ name: string; age: number }> = [];
// 或者使用接口:let users: Array<User> = [];两种语法(Type[] 和 Array<Type>)效果相同。选择取决于个人品味和上下文。我个人更喜欢对简单类型使用 Type[],对复杂的泛型结构使用 Array<Type>。但最重要的是在项目中保持一致。
方法 4:创建带有初始对象的数组
通常,数组不仅需要声明,还需要立即填充数据。TypeScr