键入调整函数



我希望设置一个函数,该函数接受一个索引、一个函数和一个数组,并返回该数组的克隆,除了使用该函数调整指定索引处的项。

const adjust = <T, U extends T[], V extends number>(index: V) =>
(f: (x: U[V]) => U[V]) => (xs: T[]) =>
Object.assign([], xs, { [index]: f(xs[index]) });

我希望这将返回类型U,但它返回类型:

never[] & T[] & {
[x: number]: U[V];
}

有什么想法可以让它返回一个更可用的类型吗?

做你想做的事情的简单方法:

function modifyItem<T>(array: T[], index: number, modifier: (item: T) => T): T[] {
return array.map((item, i) => i === index ? modifier(item) : item);
}

或者,如果你想用元组保留所有类型信息:

function modifyItem<T extends unknown[], U extends keyof T>(array: T, index: U, modifier: (item: T[U]) => T[U]): T {
const result = [...array] as T;
result[index] = modifier(result[index]);
return result;
}

带有currying的更多功能风格版本:

const modifyItem =
<T extends unknown[]>(array: T) =>
<U extends number>(index: U) =>
(modifier: (item: T[U]) => T[U]) => [
...array.slice(0, index),
modifier(array[index]),
...array.slice(index + 1)
] as T;

无法理解为什么需要将一个转换拆分为三个单独的函数,这只会使整个解决方案变得复杂。可能是:

function customClone<T>(array: T[], index: number, modifier: (elem: T) => T): T[] {
const resultArray = array.slice();
resultArray.splice(index, 1, modifier(array[index]));
return resultArray;
}

提示:应该在可能传递错误index的情况下进行处理。

最新更新