重拾Typescript之keyof

177 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

1.keyof:

首先通过keyof最先让笔者想到的就是Object.keys,类比记忆下效果要好些吧,

ts中的keyof也是类似的作用,能够通过keyof来获取属性的名称。

keyof:该操作符可以用于获取某种 类型 的所有键(key);

然后将所有的 键key 作为一个新的类型(类似于枚举的效果)

其返回类型是 联合类型,简单的说,它是作用于类型的,返回类型为联合类型

例子:

interface TestKeyof{
  name: string,
  age: number,
  sex: 0 | 1
}

type One = keyof TestKeyof

interface ITest {
  key: One
}

//
let test:ITest = {
  key: "name" // name | age | sex
}

分析:

  • 通过keyof获取TestKeyof接口中的类型然后赋值给type One
  • 然后新建ITest接口,key的类型为One
  • 最后创建一个test对象进行测试,test是通过Itest接口进行约束的,那么必须得有一个key的属性,并且这个key的键值必须是 name | age | sex的一种,其实是联合类型

2.keyof在泛型中的使用:

**场景:**在ts中,在某个函数中,需要根据参数key返回某个对象的key的属性值

interface NBA{
  name:string;
  age:number;
  gender:string;
}

class NBAOrization{
  constructor(private info:NBA){

  }
  
  getInfo(key:string){
    if(key==='name' || key === 'age' || key==='gender'){
      return this.info[key];
    }
  }
  
  useKeyofToGetInfo<T extends keyof NBA>(key:T):NBA[T]{
    return this.info[key];
  }
}

const one = new NBAOrization({
  name:'科比布莱恩特',
  age:18,
  gender:'male'
})

const res = one.getInfo('name');
const res1 = one.NBAOrization('name');

console.log('我是res',res); //科比布莱恩特
consoel.log('我是res1',res1);//科比布莱恩特

分析:

  • NBAOrization类接受一个初始化创建实例的时候接收一个参数info

  • info通过接口NBA进行约束,里面有name、age、gender属性

  • 如果不使用keyof那么我们只能通过判断某个属性是否存在这个key属性,然后返回info[key],比如上面例子中的getInfo方法

  • 使用keyof结合泛型T extends keyof NBA,从而让T成为了name | age | gender联合类型

抽象出来就是如下:

// 两个参数,第一个参数为对象,第二个参数为对象中的属性名,
// 将对象中对应的属性值返回

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