讲解
keyof 作用于一个对象类型,得到它所有键的联合:keyof { a: string; b: number } 是 "a" | "b"。它是连接「对象结构」和「字符串字面量」的桥梁——上一章的 pick 函数、表单的字段名参数、i18n 的文案 key,背后都是 keyof。对联合类型取 keyof 得到的是各成员键的交集(共有键),对 any 取 keyof 得到 string | number | symbol,这些边角了解即可。
typeof 则走另一个方向:从一个值拿到它的类型。JavaScript 本来就有运行时 typeof 运算符,TypeScript 在类型位置复用了这个关键字:const user = { name: "林" }; type User = typeof user 让类型跟随实现,改实现时类型自动更新,避免「两处定义、逐渐漂移」。配合 as const,typeof 是提取字面量联合的主力(枚举章节的 Theme 例子已经见过)。
两者经常联手:(typeof CONFIG)[keyof typeof CONFIG] 表示「CONFIG 所有值的联合类型」,是从常量对象提取「可取值范围」的标准公式。记住这三个操作的位置感:keyof 后是类型,typeof 后是值,T[K] 用类型索引出属性的类型——索引访问类型 T["a"] 本身也是一个独立技能,取嵌套结构里的某一层特别好用。
示例
keyof 得到键的联合:
interface Product {
sku: string;
name: string;
price: number;
}
type ProductKey = keyof Product; // "sku" | "name" | "price"
function printField(product: Product, key: ProductKey): void {
console.log(`${key} => ${String(product[key])}`);
}
const p: Product = { sku: "KB-001", name: "键盘", price: 299 };
printField(p, "name");
printField(p, "price");
typeof 从值提取类型,实现与类型同源:
const defaultOptions = {
pageSize: 20,
sort: "createdAt",
asc: false,
};
type Options = typeof defaultOptions;
function buildQuery(overrides: Partial<Options>): Options {
return { ...defaultOptions, ...overrides };
}
const q = buildQuery({ pageSize: 50 });
console.log(`每页 ${q.pageSize} 条,按 ${q.sort} 排序`);
索引访问类型取嵌套层级,配合 keyof + typeof 的公式:
const ROUTES = {
home: "/",
bookList: "/books",
bookDetail: "/books/:id",
} as const;
type RoutePath = (typeof ROUTES)[keyof typeof ROUTES]; // "/" | "/books" | "/books/:id"
type BookDetailRoute = (typeof ROUTES)["bookDetail"]; // 精确取一层
function navigate(path: RoutePath): string {
return `跳转到 ${path}`;
}
const detail: BookDetailRoute = ROUTES.bookDetail;
console.log(navigate(ROUTES.home), detail);
常见坑
- keyof 用于具体值:keyof 后面必须是类型,对值要用 typeof 先转类型:keyof typeof config。
- 以为 T[K] 是运行时取值:类型位置的 T[K] 是「属性类型查询」,发生在编译期;运行时取值是 obj[key],两者别混。
- 对联合类型 keyof 结果吃惊:keyof (A | B) 是共有键的交集,不是并集——想操作各自键先收窄。
- typeof 一个 any 值:得到 any,公式全部失效;源头的常量要有明确类型。
小结
keyof:类型 → 键的联合;typeof:值 → 类型;T[K]:类型 → 属性类型。三者组合出「跟随实现」的类型工具。下一章看官方造好的一篮子工具类型。