【问题标题】:Typescript Types: Type of object value which can be used as index signatureTypescript Types:可用作索引签名的对象值的类型
【发布时间】:2019-12-22 17:48:50
【问题描述】:

我想写一个数组到对象函数,它提取一个属性作为索引,比如:

export const arrayToObject
    = <T, K extends keyof T, V extends T[K] & string>(arr: T[], key: K): { [v: V]: T } =>
    Object.assign({}, ...arr.map(item => ({[item[key]]: item})));

但它给出了一个编译错误,说 An index signature parameter type must be 'string' or 'number'V,尽管我将 V 类型限制为 string。为什么会出现错误,正确的方法是什么?

【问题讨论】:

    标签: typescript types typescript-typings typescript2.0


    【解决方案1】:

    我还找到了一个可行的解决方案,似乎更轻松:

    export const arrayToObject =
       <T extends {[k in K]: number | string}, K extends keyof T>(arr: T[], key: K): { [k in T[K]]: T } =>
          Object.assign({}, ...arr.map(item => ({ [item[key]]: item })));
    

    【讨论】:

      【解决方案2】:

      V 可以扩展 T[K]。但是由于当您使用item[key] 进行索引时,T 不受任何约束,所有编译器都会知道item[key] 的类型为T[K]。您需要约束 T 以便键 K 的值是与属性键兼容的类型。

      
      export const arrayToObject
          = <T extends Record<K, V>, K extends keyof T, V extends PropertyKey>(arr: T[], key: K): { [v in T[K]]: T } =>
          Object.assign({}, ...arr.map(item => ({[item[key]]: item})));
      
      
      let r = arrayToObject([{ key: "A", value: 0 }, { key: "B", value: 0 }], "key");
      r.A.value //ok
      r.B.value //ok
      r.C.value //err
      
      

      Play

      【讨论】:

        猜你喜欢
        • 2016-01-25
        • 1970-01-01
        • 2016-04-07
        • 2023-03-13
        • 2019-11-23
        • 2017-06-11
        • 2017-08-02
        • 2020-02-02
        • 1970-01-01
        相关资源
        最近更新 更多