首页 / TypeScript 入门教程 / keyof 类型操作符

TypeScript 入门教程

keyof 类型操作符

本教程共 80 篇 · 第 45 篇 · 更新于 2026-08-10 · 约 8 分钟阅读

TypeScriptTypeScript 入门教程keyof类型操作符泛型约束

本节目标:理解 keyof 操作符的作用——把对象类型的键提取成一个联合类型,并学会用它配合泛型约束写出类型安全的属性访问函数。

什么是 keyof

keyof 是一个类型操作符,它接收一个对象类型,返回该类型所有键名组成的联合类型。可以把 keyof 想象成”把这个类型的所有 key 列出来”。

type Person = {
  name: string;
  age: number;
  location: string;
};

// P 的类型是 "name" | "age" | "location"
type P = keyof Person;

P 不是宽泛的 string,而是这三个具体字面量的联合。这意味着你只能给 P 类型的变量赋这三种值之一:

let key: keyof Person;
key = "name";     // ✅
key = "age";      // ✅
// key = "email"; // ❌ Person 上没有 email

为什么需要 keyof

假设你写了一个函数,想安全地从对象中取出某个属性的值。最朴素的做法是用 string 作为键的类型:

function getProperty(obj: Person, key: string) {
  return obj[key]; // ❌ 类型不安全——key 可能是 "email" 这种不存在的属性
}

keyof 解决了这个问题:它把”键的取值范围”精确限定在对象实际拥有的属性名上:

function getProperty(obj: Person, key: keyof Person) {
  return obj[key]; // ✅ 类型安全,key 只能是 "name" | "age" | "location"
}

keyof 与泛型约束联动

单独使用 keyof 有用,但它真正的威力体现在和泛型配合。你可以写一个通用的属性读取函数

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

拆解一下这个签名:

  • T 是对象类型
  • K extends keyof T 表示 K 必须是 T 的某个键名
  • 返回值 T[K]索引访问类型——属性的类型会被自动推断

使用效果:

const person: Person = {
  name: "小明",
  age: 30,
  location: "北京"
};

const name: string = getProperty(person, "name");     // ✅ 名字和类型都正确
const age: number = getProperty(person, "age");        // ✅
// const bad = getProperty(person, "email");           // ❌ 编译报错

编辑器在 getProperty(person, "") 里输入引号后会自动补全 "name" | "age" | "location",这个体验很关键——你永远不会打错属性名。

keyof 与索引签名

当类型有索引签名时,keyof 的行为会有变化。

number 索引签名

type ArrayLike = { [n: number]: unknown };
type A = keyof ArrayLike; // number

因为有 number 索引签名,keyof 返回的就是 number 本身,而不是具体的数字字面量。

string 索引签名

type StringMap = { [k: string]: boolean };
type M = keyof StringMap; // string | number

注意这里返回的是 string | number,不是单纯的 string。这是因为 JavaScript 中对象的键统一被转成字符串——obj[0]obj["0"] 等价。所以数字键也是合法的。

keyof any

keyof any 返回 string | number | symbol。这是 TypeScript 中所有可能的键类型的大合集:

type AllKeys = keyof any; // string | number | symbol

这个知识在后面讲映射类型时会用到。

小结

  • keyof TT 的所有键,返回字面量联合类型
  • 和泛型 K extends keyof T 联动,写出类型安全的属性访问函数
  • string 索引签名时,keyof 返回 string | number
  • number 索引签名时,keyof 返回 number
  • keyof any = string | number | symbol