类型为T [K]的键的Typescript通用映射映射回T本身

时间:2020-06-30 18:24:28

标签: typescript typescript-generics

我有以下代码:

type PartialRecord<K extends keyof any, T> = {
  [P in K]?: T;
};

export class CustomMaps {
  public static createInnerMap<T, K extends keyof any>(array: T[], customKey: keyof T): PartialRecord<K, T> {
    const innerMap: PartialRecord<K, T> = {};
    for (let i = 0; i < array.length; ++i) {
      innerMap[array[i][customKey] as K] = array[i];
    }
    return innerMap;
  }
}

它给出了错误:将类型“ T [keyof T]”转换为类型“ K”可能是错误的,因为这两个类型之间都没有足够的重叠。如果这是故意的,请先将表达式转换为“未知”。

它应该做什么:

  class Car {
    private color: string;
    private wheelcount: number;
    constructor(color: string, wheelcount: number) {
      this.color = color;
      this.wheelcount = wheelcount;
    }
  }
  const redCar = new Car('red', 4);
  const blueCar = new Car('blue', 8);
  const yellowCar = new Car('yellow', 6);
  const colorMap = CustomMaps.createInnerMap<Car, string>([redCar, blueCar, yellowCar], 'color');
  colorMap['red'] // should return redCar instance

  const wheelMap = CustomMaps.createInnerMap<Car, number>([redCar, blueCar, yellowCar], 'wheelcount');
  wheelMap[8] // should return blueCar instance

在不将innerMap [array [i] [customKey]]强制转换为未知的情况下,如何确保array [i] [customKey]将返回可用于索引编制的类型(特别是我替代K的类型)?

1 个答案:

答案 0 :(得分:0)

似乎我找到了解决方案,而不必使用强制转换为“未知的K”。

我设置了以下自定义类型:

type TRecordKey = string | number | symbol;
type TRecurringRecord<K extends T[keyof T] & TRecordKey, T> = {
  [P in K]?: T
}

然后我像这样调整上面的代码:

  public static recurringMap<K extends T[keyof T] & TRecordKey, T>(
    array: T[],
    customKey: keyof T
  ): TRecurringRecord<K, T> {
    const recurringMap: TRecurringRecord<K, T> = {};
    for (let i = 0; i < array.length; ++i) {
      recurringMap[array[i][customKey] as K] = array[i];
    }
    return recurringMap;
  }

现在,我们有一个泛型函数,用于创建对象映射,该映射的键是对象本身的属性。