打字稿函数定义:return 嵌套对象,键从值数组中查找

Typescript function definition: return nested object with keys looked-up from value array

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

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}}

几乎 有效,除了不推断嵌套对象的键名。第一个例子 returns:

{
    foo: {
        [x: string]: Widget;
    };
}

而我希望它 return

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

可以吗?

如果你的数组总是只包含"a""b",那么你可以定义字符串文字的联合类型:

type MyUnionType = "a" | "b"

然后定义变量fooMyUnionType[]。结果是:

declare function myFunction
  <Q extends MyUnionType[], T extends {[key: string]: Q}>
  (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 extends K[],我们现在说Q不是string[]而是K[],这意味着TS会将数组成员缩小到更具体的类型然后是字符串。