注意: 如果您是 TypeScript 新手,请先查看我们的 TypeScript 入门 教程。
对象是键值对的集合。
在 TypeScript 中,对象类型允许您定义对象的结构——它应该有哪些属性,以及这些属性应该是什么类型。
这是一个简单的对象示例。您可以阅读本教程的其余部分以了解更多信息。
示例
let user: { name: string; age: number } = {
name: "Alice",
age: 25
};
在这里,user
是一个具有两个属性的对象:name
(字符串类型)和 age
(数字类型)。
定义对象类型
在 TypeScript 中,您可以通过三种主要方式定义对象类型
1. 内联对象类型
内联对象类型是指在声明变量时直接定义对象的结构(就像在入门示例中看到的那样)。
let user: { name: string; age: number } = {
name: "Alice",
age: 25
};
在这里,{ name: "Alice", age: 25 }
是赋给 user
变量的对象。
2. 使用类型别名
您也可以使用 type
关键字创建对象类型。
type Person = {
name: string;
age: number;
};
let user: Person = { name: "Sara", age: 22 };
在这里,type Person = { ... }
创建了一个名为 Person
的类型别名,并定义了一个有效的 Person
对象应该是什么样的:它必须有两个属性——name
(字符串)和 age
(数字)。
然后,我们将对象 { name: "Sara", age: 22 }
赋给类型为 Person
的 user
变量。
注意:当您想在多个地方重用对象类型时,可以使用类型别名。
3. 使用接口
您也可以使用 interface
关键字来定义对象的结构。
interface Person {
name: string;
age: number;
}
let user: Person = { name: "Tom", age: 28 };
在这里,Person
是一个接口,它描述了一个具有两个属性的对象:name
(字符串类型)和 age
(数字类型)。
可选属性 (?)
您可以使用 ?
将属性标记为可选——这意味着对象可以包含该属性,但不是必需的。例如,
type User = { name: string; age?: number };
type Person = { name: string; age?: number };
// Valid
let user1: Person = { name: "Alice", age: 25 };
// Valid even though age is missing
let user2: Person = { name: "Bob" };
在此示例中,age
是可选的。因此,user1
和 user2
都是有效的——一个包含 age
,另一个则不包含。
对象类型作为函数参数
您还可以为函数参数使用对象类型,以精确定义传递到函数中的对象应该具有哪些属性。例如,
function greet(user: { name: string; age: number }) {
console.log(`Hello, ${user.name}. You are ${user.age} years old.`);
}
greet({ name: "Tyler", age: 43 });
在这里,greet()
函数期望一个具有两个属性的对象:name
(字符串)和 age
(数字)。
常见问题
当将对象作为参数传递给函数时,您可以使用解构来提取特定属性——并且还可以提供默认值以防这些属性丢失。
function draw({ x = 0, y = 0 }: { x?: number; y?: number }) {
console.log(x, y);
}
draw({ x: 10 }); // Output: 10 0
draw({}); // Output: 0 0
在这里,draw()
函数接受一个带有可选 x
和 y
属性的对象。使用带有 x = 0
和 y = 0
的解构提供了默认值。
如果未传递 x
或 y
,它将默认为 **0** 而不是 undefined
。
对象的只读属性
readonly
关键字使属性变为只读,这意味着您不能重新分配它。例如,
type Home = {
readonly resident: { name: string };
};
const house: Home = {
resident: { name: "Alice" }
};
// Error: Cannot assign to 'resident' because it is a read-only property
house.resident = { name: "Bob" };
在这里,resident
属性被标记为 readonly
,因此当我们尝试重新分配 resident
对象时,如下所示
house.resident = { name: "Bob" };
TypeScript 会抛出错误,因为 readonly
防止了属性的重新分配。
但是,由于内部的 name
属性未标记为 readonly
,我们仍然可以修改它
house.resident.name = "Charlie"; // This works
使用索引签名定义对象
索引签名允许您定义具有动态属性名称的对象——这意味着您不必预先知道属性名称,但仍然可以指定值的类型。
type Scores = { [subject: string]: number };
const mathScores: Scores = {
math: 95,
science: 88,
english: 76
};
在这里,[subject: string]: number
表示对象可以有任意数量的 string
键,并且每个键都必须有一个 number
值。
常见问题
您可以使用 &
(交叉类型)将多个对象类型组合成一个。结果类型必须满足所有组合类型的属性。例如,
type User = { name: string };
type Admin = { role: string };
type AdminUser = User & Admin;
const admin: AdminUser = {
name: "Alice",
role: "Super Admin"
};
在这里,AdminUser
使用 & 组合了 User
和 Admin
,因此它必须同时具有 name
和 role
属性。
另请阅读