使用映射类型将方法转换为道具

时间:2018-01-24 12:55:28

标签: typescript

我需要从具有多个通用无参数函数的通用对象中进行选择/选择,并返回一个包含正确输入的评估结果的对象。

对于道具,我可以使用以下功能签名进行选择:

function select<T, K extends keyof T>(obj:T,keys:K[]):{[P in K]:T[P]}

我想要这样的事情:

function select<T, K extends keyof T>(obj:T,keys:K[]):{[P in K]:T[P]()}

请注意返回类型中的T[P](),它不起作用,但说明了我的需要。 K也应该被keyof T & ()=>U约束,其中U对于每种方法都不同。

这可能吗?

1 个答案:

答案 0 :(得分:0)

是的,您可以使用inference from mapped types。这使您可以将函数 input 表示为映射类型,并且仍允许推断(有时)工作。

我经常发现TypeScript问题可以通过解决&#34;倒置&#34;来解决。或者&#34;向后&#34;版本的问题。例如,您的问题是当前没有(从TypeScript 2.7开始)获取函数签名并提取返回类型的方法。但是有一种方法可以采用返回类型并从中创建一个函数签名,这是&#34; backwards&#34;从你想要的。从映射类型推断可以让你像这样继续:

declare function select<T, K extends keyof T>(
  obj: {[P in keyof T]: () => T[P]}, 
  keys: K[]
): {[P in K]: T[P]};

因此T类型不再是obj的类型,而是select()的{​​{1}}的返回值的类型完整K。让我们看看它是否有效:

keyof T

如果您检查代码,您将看到编译器将通用参数推断为const obj = { foo: () => 3, bar: () => "hey", baz: () => false } const result = select(obj, ["foo", "baz"]); // result: { foo: number; baz: boolean; } T={ foo: number; bar: string; baz: boolean; } ...因此结果为K="foo"|"baz",如您所愿

希望有所帮助;祝你好运!