如何根据提供的参数键入返回对象属性的函数?

时间:2021-04-22 19:58:59

标签: typescript types typescript-generics

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

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 中所有属性类型的并集,这并不理想。

2 个答案:

答案 0 :(得分:1)

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

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

getProperty()

您可以验证它是否有效:

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

Playground link to code

答案 1 :(得分:0)

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');