您现在的位置是:亿华云 > IT科技类资讯

仅知道键和值的类型,如何定义 TS 对象类型?

亿华云2025-10-03 02:13:27【IT科技类资讯】6人已围观

简介在学习 TS 的过程中,你遇到过类似的错误么?let user = {}user.id = "TS001" // 类型“{}”上不存在属性“id”。user.name = "阿宝哥" // 类型“{}

在学习 TS 的仅知过程中,你遇到过类似的道键的类定义对象错误么?

let user = { }

user.id = "TS001" // 类型“{ }”上不存在属性“id”。

user.name = "阿宝哥" // 类型“{ }”上不存在属性“name”。和值

除了 any “大招” 之外,型何你还知道几种解决方案?类型阅读完本文,你将会找到一些答案。仅知

这是道键的类定义对象小王他的月薪是包含了基本工资和月度奖金,这是和值小郭他的月薪只包含合同工资。

const Wang = {

baseSalary: 10000,型何 // 基本工资

monthlyBonus: 2000 // 月度奖金

};

const Guo = {

contractSalary: 15000 // 合同工资

}

这里我们可以实现一个 calculateSalary 函数来计算他们的薪资,计算逻辑实现起来很简单。类型但问题来了,仅知在 TS 中如何定义该函数参数的道键的类定义对象类型呢?

function calculateSalary(salaryObject: ???) {

let total = 0;

for (const name in salaryObject) {

total += salaryObject[name];

}

return total;

}

给你 3 秒钟的时间思考一下。你想到答案了么?和值其中一种方案是使用索引签名。当我们仅知道对象键和值的型何类型时,云服务器就可以使用索引签名来定义该对象的类型类型。

这是索引签名的语法:

{ [key: KeyType]: ValueType }

其中 Key 的类型,只能是 string,number,symbol 或模版字面量类型,而值的类型可以是任意类型。

interface Dictionary {

[key: boolean]: string;

}

其中模版字面量类型是 TypeScript 4.1 版本引入的新类型,结合索引签名我们可以定义更强大的类型:

interface PropChangeHandler {

[key: `${ string}Changed`]: () => void;

}

let handlers: PropChangeHandler = {

idChanged: () => { }, // Ok

nameChanged: () => { }, // Ok

ageChange: () => { } // Error

};

了解索引签名的语法之后,我们就可以轻松地定义出 salaryObject 参数的类型:

function calculateSalary(salaryObject: { [key: string]: number }) {

let total = 0;

for (const name in salaryObject) {

total += salaryObject[name];

}

return total;

}

有些时候,在定义对象类型时,会含有一些已知和未知的键,这时我们可以结合索引签名来定义该对象的类型:

interface Options {

[key: string]: string | number | boolean;

timeout: number; // 已知的键

}

const options: Options = {

timeout: 1000,

errorMessage: The request timed out!,

isSuccess: false

};

在使用索引签名时,你可能会遇到这些困惑:

interface NumbersNames {

[key: string]: string

}

const names: NumbersNames = {

1: one,

2: two,

3: three

};

const value1 = names[1] // Ok

const value2 = names[1] // Ok

type N0 = keyof NumbersNames // string | number为什么可以通过字符串 1 和数字 1 来访问对应的云服务器提供商属性值。为什么 keyof NumbersNames 返回的 string 和 number 类型组成的联合类型。

这是因为当用作属性访问器中的键时,JavaScript 会隐式地将数字强制转换为字符串,TypeScript 也会执行这种转换。

除了使用索引签名之外,我们还可以使用 TS 内置的工具类型 Record 类型来定义 calculateSalary 函数的参数类型:

type Record= {

[P in K]: T;

};

function calculateSalary(salaryObject: Record) {

let total = 0;

for (const name in salaryObject) {

total += salaryObject[name];

}

return total;

}

那么索引签名和 Record 工具类型有什么区别呢?在一些场合下,它们都能定义出期望的类型。

const user1: Record= { name: "阿宝哥" }; // Ok

const user2: { [key: string]: string } = { name: "阿宝哥" }; // Ok

对于索引签名来说,其键的类型,只能是 string,number,symbol 或模版字面量类型。而 Record 工具类型,键的类型可以是字面量类型或字面量类型组成的联合类型:

type User1 = {

[key: "id"]: string; // Error

};

type User2 = {

[key: "id" | "name"]: string; // Error

};

type User3 = Record<"id", string>; // Ok

type User4 = Record<"id" | "name", string>; // Ok

const user: User4 = {

id: "TS001",

name: "阿宝哥",

};

看完以上内容,你学会索引签名和 Record 工具类型了么?

服务器租用

很赞哦!(3)