【问题标题】:How to type functions that return properties of objects based on argument provided?如何键入基于提供的参数返回对象属性的函数?
【发布时间】:2021-07-17 01:45:01
【问题描述】:

如果我们有一个函数,它从给定对象和字符串属性名称作为参数的对象返回属性值,我们将如何为其编写类型定义?

const obj = {
    name: 'Hello',
    age: 32,
};

function getProp<OBJ>(obj: OBJ, propname: keyof OBJ): DONT_KNOW_TYPE {
    return obj[propname];
}

const name = getProp(obj, 'name');

我们如何正确键入返回值,以便强制执行 propname 参数请求的属性的属性类型?本质上,应该用什么来代替DONT_KNOW_TYPE

当然anyOBJ[keyof OBJ] 是可能的,但它并没有明确强制第二个参数中声明的属性类型,并且默认情况下,typescript 推断函数的返回类型是所有OBJ 中的属性类型不太理想。

【问题讨论】:

    标签: typescript types typescript-generics


    【解决方案1】:
    const obj = {
        name: 'Hello',
        age: 32,
    } as const;
    
    function getProp<T extends typeof obj, K extends keyof T>(obj: T, propname: K): T[K] {
        return obj[propname];
    }
    
    const name = getProp(obj, 'name');
    

    【讨论】:

      【解决方案2】:

      您想让propname 的类型成为generic 类型参数,如K extends keyof OBJ(好吧,T,而不是OBJ,因为OBJ 不是常规类型参数名称),然后使用indexed access types表示属性类型:T[K]

      这看起来非常接近(now deprecated) documentation for indexed access types 中显示的getProperty() 函数:

      function getProperty<T, K extends keyof T>(o: T, propertyName: K): T[K] {
        return o[propertyName]; // o[propertyName] is of type T[K]
      }
      

      您可以验证它是否有效:

      const name = getProperty(obj, 'name');
      // const name: string
      console.log(name.toUpperCase()); // "HELLO"
      

      Playground link to code

      【讨论】:

        猜你喜欢
        • 2020-09-04
        • 1970-01-01
        • 2020-05-14
        • 1970-01-01
        • 2019-03-08
        • 1970-01-01
        • 2021-01-11
        • 1970-01-01
        • 2019-06-07
        相关资源
        最近更新 更多