【问题标题】:Typescript function definition: return nested object with keys looked-up from value array打字稿函数定义:返回嵌套对象,其中键从值数组中查找
【发布时间】:2020-05-18 22:55:36
【问题描述】:

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

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: {
        [x: string]: Widget;
    };
}

而我希望它返回

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

可以吗?

【问题讨论】:

    标签: javascript typescript function signature .d.ts


    【解决方案1】:

    为了让 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 会将数组的成员缩小到比字符串更具体的类型。

    【讨论】:

      【解决方案2】:

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

      type MyUnionType = "a" | "b"
      

      然后将变量foo 定义为MyUnionType[]。结果是:

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

      应该工作:)


      但是如果你的数组总是由不同的字符串组成,那么就不可能实现这样的类型,因为 TypeScript 只是设计时工具

      【讨论】:

      • 一般来说,动态键推断确实有效。例如。签名的更简单、非嵌套版本的行为符合预期:javascript declare function myFunc&lt;T extends string[]&gt;(keys: T) : {[key in T[number]]: Widget}; myFunc(['a', 'b']) //==&gt; {a: Widget, b: Widget}
      猜你喜欢
      • 2019-08-03
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      • 2017-12-24
      • 2021-06-28
      • 1970-01-01
      相关资源
      最近更新 更多