TypeScript-推断或声明Pick类型作为函数的返回值

时间:2019-02-11 19:05:37

标签: typescript

考虑以下简化函数,该函数接受一个对象和该对象的属性,并返回仅具有指定属性的该对象的克隆:

export function clonePick<T, K extends keyof T>(obj: T, prop: K) {
  const keys = Object.keys(obj).filter(k => k === prop)
  return keys.reduce(
    (clone: any, key: string) => {
      return { ...clone, [key]: obj[key as keyof T] };
    },
    {}
  );
}

除了值而不是类型之外,这与Pick基本上是相同的行为,因此它的返回类型可以表示为:

Pick<T, prop>

除上述无效的打字稿外。但是,调用函数时,我们可以在运行时知道prop well 的值:

interface ITest {
  numProp: number;
  strProp: string;
}

const test = { numProp: 1, strProp: '1' }; // <-- type is ITest

const testClone = clonePick(test, 'numProp') // <-- type is any

我可以轻松地明确声明这一点:

const testClone: Pick<ITest, 'numProp'> = clonePick(test, 'numProp')

但是,如果我可以将该行为作为上述功能的一部分,它将具有更大的可维护性。这可能吗?最好它可以使用一系列属性以及单个道具

1 个答案:

答案 0 :(得分:1)

您不会让编译器推断对reduce的复杂Pick调用,甚至对于{ [prop]: obj[prop] }之类的简单事情也不会。最好的选择是对函数的返回类型使用注释。

export function clonePick<T, K extends keyof T>(obj: T, prop: K): Pick<T,K> {

  return { [prop]: obj[prop] } as any;
}


interface ITest {
  numProp: number;
  strProp: string;
}

const test = { numProp: 1, strProp: '1' }; // <-- type is ITest

const testClone = clonePick(test, 'numProp') // 

testClone.numProp
testClone.strProp // err