在 TypeScript 中声明并键入嵌套对象
Declare and Type a nested Object in TypeScript
使用接口或类型别名在 TypeScript 中键入嵌套对象。您可以在指向嵌套对象的界面上设置属性。对象的类型可以根据需要具有尽可能深的嵌套属性。
索引.ts
interface Person { name: string; address: { country: string; city: string; }; } const person: Person = { name: 'James', address: { country: 'Chile', city: 'Santiago', }, };
我们使用
接口
来键入具有嵌套属性的对象。
该address
属性指向一个具有country
和city
类型属性的对象string
。
您也可以使用
类型别名
来获得相同的结果。
索引.ts
// 👇️ using type alias type Person = { name: string; address: { country: string; city: string; }; }; const person: Person = { name: 'James', address: { country: 'Chile', city: 'Santiago', }, };
类型别名和接口之间存在一些细微差别,但是上面的示例完全相同。
您可能还会在网上看到内联键入嵌套对象的示例。
索引.ts
const person: { name: string; address: { country: string; city: string }; } = { name: 'James', address: { country: 'Chile', city: 'Santiago', }, };
但是,尤其是对于嵌套对象,内联类型非常难以阅读,应该避免使用。
如果你声明一个嵌套对象并初始化它的所有键值对,你可以让 TypeScript 推断它的类型。
索引.ts
/** * const person: { name: string; address: { country: string; city: string; }; } */ const person = { name: 'James', address: { country: 'Chile', city: 'Santiago', }, };
TypeScript 能够根据我们在初始化时提供的键值对推断对象的类型。
这是了解某物类型的一种非常简单的方法——用值对其进行初始化,将其分配给变量并将鼠标悬停在变量上以查看其推断类型。
如果您没有提前拥有嵌套对象的所有值,则可以
通过在类型定义中使用问号将它们标记为可选。
索引.ts
type Person = { name: string; address?: { // 👈️ address is optional country: string; city: string; }; }; const person: Person = { name: 'James', }; person.address = { country: 'Chile', city: 'Santiago', };
我们将嵌套对象上的属性标记address
为可选,因此我们不需要在初始化对象时提供它。
将属性标记为可选,意味着它可以具有其定义的类型或者是
undefined
.
如果您事先不知道对象属性的所有名称,则可以使用
索引签名。
索引.ts
type Person = { name: string; address: { country: string; city: string; [key: string]: any; // 👈️ index signature }; }; const person: Person = { name: 'James', address: { country: 'Chile', city: 'Santiago', }, }; person.address.street = 'Example str. 123'; person.address.postCode = 123;
该{[key: string]: any}
语法是 TypeScript 中的
索引签名
,当我们事先不知道类型属性的所有名称和值的形状时使用。
示例中的索引签名意味着当
address
嵌套对象用 a 索引时string
,它将返回一个类型的值。 any
{[key: string]: string}
您可能还会在示例中看到索引签名。它代表一个键值结构,当用 a 索引时string
返回一个 type 的值string
。
该示例显示了即使我们没有定义address.street
或
address.postCode
属性,我们仍然能够在嵌套对象上设置它们。