keyof 类型操作符
keyof 是TS的类型操作符,用于获取对象类型的所有键名组成的联合类型.
注意: keyof 是获取对象类型的所有键名,不是对象变量的建名. 一定要把变量和类型分清楚.
1 获取一个对象类型的键名
interface ObjectInfo {
error:string;
info:string
}
type keys = keyof ObjectInfo;
// keys: "error"|"info"
"error"|"info" 就是keyof取ObjectInfo对象的健明组成的联合类型.
const k1:keys = "error"; // 正确
const k2:keys = "info"; // 正确
const k2:keys = "success"; // 错误
2 获取数组类型的方法键名
type Arraykeys = keyof Array<any>;
const ak1:arrayKeys = "push"; // 正确
const ak2:arrayKeys = "length"; // 正确
const ak3:arrayKeys = "slice"; // 正确
const ak4:arrayKeys = "some"; // 正确
const ak5:arrayKeys = "abc"; // 错误
3 索引签名
3.1 字符串索引签名: {[key: string]:any }
type IndexSignatureString = {[n: string]: any};
type I = keyof IndexNum; // type I = number|string 为什么n:string的时候 I是的类型是number和string组成的联合类型. TS官方有说明.因为Javascript总是把对象健名转换成字符串. 在JS中obj[0]->obj['0'].我的理解是为了兼容.
const I1:I = 1; // 正确
cosnt I2:I = "1"; // 正确
3.2 数字索引签名: {[n: number]: any}
type IndexSignatureNumber = {[n: number]: any};
type In = keyof IndexSignatureNumber; // type In = number
const In1:In = 1; // 正确
const In2:In = "1"; // 错误
4 索引签名使用
// 索引签名- 将数组转换成对象
const ArrayIndexToObject = <T,>(arr[T]): {[index: number]: T} =>{ //, 避免与JSX的语法冲突所以加了","
return arry.reduce((obj, item, index) => {
obj[item] = item;
return obj;
}, {} as {[index:number]: T})
}
console.log(ArrayIndexToObject([11,12,34,55,66]));
//{
// "0": 11,
// "1": 12,
// "2": 34,
// "3": 55,
// "4": 66
//}
5 索引签名作为动态属性使用
interface Config {
darkMode: boolean;
notification: boolean;
[key:string]: boolean; //动态属性. 引用Config类型的时候可以写多个.这里的[key:string]:boolean 只是一个占位符.
}
function isDisabled<T extends keyof Config>(config:Config, key: T):Config[T] {
return config[key];
}
const config:Config = {
darkMode:true,
notification: true,
isEnable: true, // isEable 动态属性名
maxLength:true, // maxLength 动态属性名
}
console.log(isDisabled(config, "isEnable")); // true;
console.log(isDisabled(config, "maxLength")); // true;
console.log(isDisabled(config, "isTrue")); // undefined;
6 索引签名的约束性
在上面Config接口中定义了{[key:string]: boolean}字符窜索引签名, 接口中其它属性的值必须是boolean. 比如在Config接口加一个"node"属性其值是"abc"时, TS会报错:Property 'node' of type 'string' is not assignable to 'string' index type 'boolean'. 这个特性在需要有统一类型值的场景非常有用.
TS为什么有这个规定我也想不明白,可能是学的还不够到位,希望网友给出见解.
interface Config {
node: string; // 错误
darkMode: boolean;
notification: boolean;
[key:string]: boolean;
}
//如果想要接口Config中的属性只是其它类型可以这样做:
interface Config {
node: string; // 正确
darkMode: boolean;
notification: boolean;
[key:string]: boolean | string; //....|....或者any,或者更具体的泛型T
}
7 只读索引签名
在索引签名前面加上readonly 进行修饰. 这样: readonly [key:string]:boolean
interface Config {
readonly [key:string]:boolean; // 只读索引起签名
darkMode:boolean;
notification:boolean;
}
const configIn:Config = {
darMode:true,
notification:true,
isTrue: false
}
configIn['isMaxLength'] = true // 错误不允许添加isMaxLength 属性.
8 模板字面量索引签名
interface Config {
[key: `chappy${string}]: any; //表示这个变量key 字符串必须是"chappy....."
}
cosnt Te:Config = {
chappy123: 123 //ok
}

浙公网安备 33010602011771号