TypeScript keyof操作符
keyof
类型操作符
对一个对象类型使用keyof操作符,会返回该对象属性名组成的一个字符串或者数字字面量的联合。
type Point = {
x: number,
y: number
}
type P = keyof Point; //type P = 'x'|'y'
let x: P = 'z'; // 报错:不能将类型“"z"”分配给类型“keyof Point”
但如果这个类型有一个string
或者number
类型的索引签名,keyof
则会直接返回这些类型:
type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish; // type A = number
type Mapish = { [k: string]: boolean };
type M = keyof Mapish; // type M = string | number
注意在这个例子中,M
是 string | number
,这是因为 JavaScript 对象的属性名会被强制转为一个字符串,所以 obj[0]
和 obj["0"]
是一样的。
数字字面量联合类型
在一开始我们说了,keyof
也可能返回一个数字字面量的联合类型,当对象的key为数字类型时,则会返回数字字面量的联合:
const numberObj = {
[1]: 'zs',
[2]: 'ls',
[3]: 'zl',
};
type A = typeof numberObj;
//type A = {
// 1: string;
// 2: string;
// 3: string;
// }
type B = keyof A; // type B = 1 | 2 | 3
Symbol
其实TypeScript也可以支持symbol类型的属性名:
const s1 = Symbol();
const s2 = Symbol();
const s3 = Symbol();
const symbolToNumberMap = {
[s1]: 1,
[s2]: 2,
[s3]: 3,
}
type KS = keyof typeof symbolToNumberMap; // type KS = typeof s1 | typeof s2 | typeof s3
类和接口
对类使用keyof
:
class A {
name!: "zs"
}
type res = keyof A;
// type res = "name"
class B {
[1]: string = "ls";
}
type b = keyof B;
// type b = 1
对接口使用keyof
:
interface A {
name: "string";
}
type result = keyof A;
// type result = "name"