TypeScript 对象类型

注意: 如果您是 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 } 赋给类型为 Personuser 变量。

注意:当您想在多个地方重用对象类型时,可以使用类型别名。

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 是可选的。因此,user1user2 都是有效的——一个包含 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() 函数接受一个带有可选 xy 属性的对象。使用带有 x = 0y = 0 的解构提供了默认值。

如果未传递 xy,它将默认为 **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 使用 & 组合了 UserAdmin,因此它必须同时具有 namerole 属性。


另请阅读

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战