pluck

时间:2017-09-06 06:29:44

标签: typescript

TypeScript documentation给出了以下用于定义pluck函数的示例,使用“索引类型”(略有修改):

function pluck<T, K extends keyof T>(o: T, name: K): T[K] {
  return o[name];
}

显然被称为

pluck({a: 1}, 'a')

但是,我想定义一个只占用属性名称的pluck,并生成一个可以应用于对象以获取该属性的函数,如

const getA = pluck('a');
getA({a: 1})

我尝试了以下内容:

function pluck<T, K extends keyof T>(p: K) {
  return function(o: T): T[K] {
    return o[p];
  };
}

编译很好,但是当我尝试使用它时:

const a = {a: 1};
const getA = pluck('a');
console.log(getA(a));

我收到错误

  

“a”类型的参数不能分配给“never”类型的参数。 [2345]

在我呼叫pluck('a')的行上。有什么办法可以做我想要的吗?

1 个答案:

答案 0 :(得分:4)

您可以通过将T类型定义移动到内部函数并为其定义约束来实现此目的:

function pluck<KeyType extends string>(p: KeyType) {
  return function <T extends Record<KeyType, any>>(o: T): T[KeyType] {
    return o[p];
  };
}

const getA = pluck('a');

const a = { a: 1 };
console.log(getA(a));

const b = { b: 1 };
console.log(getA(b)); //error