TypeScript keyof 怎么用

很多前端朋友刚用 TypeScript 时,常觉得它比 JavaScript 多了些“条条框框”,但这些框框其实能帮我们少踩很多运行时的坑——比如想提取一个对象里所有属性的名字时,不用再手动写死字符串,keyof 就能派上用场。

先搞懂:`keyof` 到底是啥?

简单说,keyof 就是“把一个对象的所有属性名,变成一个固定的类型集合”。举个生活化的例子:你有个“奶茶订单”对象,里面有三个属性:size: "中杯"、sugar: "少糖"、temperature: "热饮",那这个订单的所有属性名就是"size"、"sugar"、"temperature",keyof 就会把这几个名字变成一个专属的类型,只能用这三个名字当值,别的都不行。

TypeScript keyof 怎么用

基础用法:直接提取对象的属性类型

先写个基础的对象类型,再用 keyof 拿它的属性名类型:

`typescript

// 定义一个用户信息的类型,对应对象的结构

type User = {

name: string;

age: number;

email: string;

};

// 用 keyof 提取 User 所有属性名的类型

type UserKey = keyof User;

`

这时候 UserKey 就相当于"name" | "age" | "email"——是一个只能取这三个值的联合类型。比如你写个函数,要专门用来拿用户某个属性的值,就可以用它来限制参数:

`typescript

function getUserInfo(user: User, key: UserKey) {

return user[key]; // 只会允许你传 name、age、email

}

// 正确用法:传的是合法的属性名

getUserInfo({ name: "小周", age: 25, email: "zhou@xxx.com" }, "name");

// 错误用法:传"phone",不在 User 的属性里,TypeScript 会直接标红报错

getUserInfo(user, "phone");

`

是不是很实用?再也不用担心写错属性名,运行时才发现phone不存在的问题了。

进阶用法:对泛型对象的属性做限制

如果遇到“不知道对象具体结构,但要限制只能用它的属性”的场景,keyof 搭配泛型会更灵活。比如要写一个“更新用户信息”的函数,只能改现有的属性,不能加新属性:

`typescript

// 泛型 T 是传入的对象类型,K 必须是 T 的属性名(用 keyof T 约束)

function updateUser<T, K extends keyof T>(user: T, key: K, value: T[K]) {

user[key] = value;

}

// 用 User 类型测试

const myUser: User = { name: "小周", age: 25, email: "zhou@xxx.com" };

// 正确:改 name 属性,值是 string 类型

updateUser(myUser, "name", "小张");

// 正确:改 age 属性,值是 number 类型

updateUser(myUser, "age", 26);

// 错误:改不存在的"gender"属性,TypeScript 会报错

updateUser(myUser, "gender", "男");

// 错误:给 age 传 string 类型的值,和 User 里 age 的 number 类型不匹配

updateUser(myUser, "age", "二十六");

`

这里的K extends keyof T就是说,K只能是T的属性,既保证了属性存在,还让值的类型和原属性匹配,相当于同时做了“属性合法性”和“值类型检查”。

注意:`keyof` 不止能用在普通对象上

除了普通对象,keyof 还能用于数组、类甚至枚举的属性名:

比如数组的话,keyof (string[])会得到"length" | "push" | ...这些数组的内置方法和属性;如果是类,keyof 会提取类的公有属性和方法的名字。不过用得最多的还是普通对象,记住“keyof是提取对象属性名的类型集合”这个核心就够了。

总结一下,keyof 就是 TypeScript 给我们的“属性名合法性检查工具”,从简单的属性读取函数,到灵活的泛型函数,它都能帮我们提前挡住写错名字、传错值的坑,让代码更安全,写起来也更省心。

上一篇 Swift编程语言如何助力iOS应用开发实现高效流畅的用户体验