我目前正在尝试创建一个纯函数,该函数接受一个对象,其属性键的子集和一个回调。该函数应克隆对象,然后将回调应用于指定的键。我遇到麻烦了,因为我似乎无法弄清楚如何正确保证这些键所访问的属性的类型。这是我正在使用的代码:
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;
}
但是编译器会抛出相同的错误。我不太确定该如何进行,或者这是否是解决问题的有效方法。有什么想法吗?