TypeScript:修改计算属性时如何正确实施类型?

时间:2019-01-18 02:27:16

标签: typescript types

我目前正在尝试创建一个纯函数,该函数接受一个对象,其属性键的子集和一个回调。该函数应克隆对象,然后将回调应用于指定的键。我遇到麻烦了,因为我似乎无法弄清楚如何正确保证这些键所访问的属性的类型。这是我正在使用的代码:

type DateModifier = (d: Date) => Date;
function modifyDates<T, K extends keyof T>(
  item: T,
  dateModifier: DateModifier,
  ...keysToMod: K[],
): T {
  const clone = Object.assign({}, item);
  keysToMod.forEach((k) => {
    if (clone[k] instanceof Date) {
      clone[k] = dateModifier(clone[k]);
    }
  });

  return clone;
}

但是编译器抗议以下错误:

Argument of type 'T[K]' is not assignable to parameter of type 'Date'.

我尝试了几种不同的解决方案,但我认为到目前为止,我最好的尝试是尝试强制K扩展T的键的子集,这些键的值的类型为'Date:'

type DateModifier = (d: Date) => Date;

type SubtypeDatesOnly<T> = Pick<T, {
  [K in keyof T]: T[K] extends Date ? K : never;
}[keyof T]>;

function modifyDates<T, K extends keyof SubtypeDatesOnly<T>>(
  item: T,
  dateModifier: DateModifier,
  ...keysToMod: K[],
): T {
  const clone = Object.assign({}, item);
  keysToMod.forEach((k) => {
    if (clone[k] instanceof Date) {
      clone[k] = dateModifier(clone[k]);
    }
  });

  return clone;
}

但是编译器会抛出相同的错误。我不太确定该如何进行,或者这是否是解决问题的有效方法。有什么想法吗?

0 个答案:

没有答案