Javascript Typescript函数定义:返回嵌套对象,并从值数组中查找键

Javascript Typescript函数定义:返回嵌套对象,并从值数组中查找键,javascript,typescript,function,signature,.d.ts,Javascript,Typescript,Function,Signature,.d.ts,我有一个方法,它把一个值是字符串数组的对象作为输入;它返回一个对象,其值是键等于字符串值的对象。例如 myFunction{foo:['a',b']}/==>{foo:{a:Widget,b:Widget} 我试图定义这个函数的签名。我最好的尝试是: declare function myFunction <Q extends string[], T extends {[key: string]: Q}> (keys: T) : {[key1 in keyof T]: {[k

我有一个方法,它把一个值是字符串数组的对象作为输入;它返回一个对象,其值是键等于字符串值的对象。例如

myFunction{foo:['a',b']}/==>{foo:{a:Widget,b:Widget} 我试图定义这个函数的签名。我最好的尝试是:

declare function myFunction
  <Q extends string[], T extends {[key: string]: Q}>
  (keys: T) : {[key1 in keyof T]: {[key2 in T[key1][number]]: Widget}}
而我希望它能回来

{
    foo: {
        a: Widget;
        b: Widget;
    };
}

可以这样做吗?

如果数组始终只包含a和b,则可以定义字符串文本的联合类型:

类型MyUnionType=a | b 然后将变量foo定义为MyUnionType[]。结果是:

声明函数myFunction keys:T:{[key1 in keyof T]:{[key2 in MyUnionType]:Widget} 应:


但是如果您的数组总是由不同的字符串组成,则不可能实现这种类型化,因为TypeScript只是设计时工具

为了允许TS修复推断,我们需要为数组键成员添加额外的泛型类型:

declare function myFunction
  <Q extends K[], T extends {[key: string]: Q}, K extends string>
  (keys: T): { [key1 in keyof T]: { [key2 in T[key1][number]]: Widget } }


注意Q扩展了K[],我们现在说Q不是string[],而是K[],这意味着TS将数组的成员缩小到比string更具体的类型。

一般来说,动态键推断是有效的。例如,签名的一个更简单、非嵌套版本的行为与预期的一样:javascript声明函数myFunckeys:T:{[key in T[number]]:Widget};myFunc['a','b']/==>{a:Widget,b:Widget}
declare function myFunction
  <Q extends K[], T extends {[key: string]: Q}, K extends string>
  (keys: T): { [key1 in keyof T]: { [key2 in T[key1][number]]: Widget } }