Итак, эта хитрая функция принимает функцию fn
и число n
и возвращает функцию-обертку, которая вызывает fn
с измененным n
-ым аргументом. n
-й аргумент fn
является объектом, свойство plugins
которого является массивом PluginObject
объектов, тогда как n
-й аргумент возвращаемой функции должен иметь немного другой тип: ее свойство plugins
Array<string | PluginObject>
, также он может иметь необязательное свойство pluginSearchDirs: string[]
, остальные свойства взяты из типа n
-ого аргумента исходной функции fn
.
Вопрос в том, как на Земле я могу преобразовать это в TypeScript?
function withPlugins(fn, n) {
return (...args) => {
const opts = args[n];
args[n] = {
...opts,
plugins: loadPlugins(opts.plugins, opts.pluginSearchDirs)
};
return fn(...args);
};
}
Вот что я пробовал, но это не сработало (withPlugins(myFn, 0)
имеет тот же тип, что и myFn
, детская площадка ) :
interface PluginObject {
foo: any;
}
declare function loadPlugins(
plugins?: (PluginObject | string)[],
pluginSearchDirs?: string[]
): PluginObject[];
function withPlugins<
Args extends any[],
Result,
OptsIdx extends number
>(
fn: (...args: Args) => Result,
optsArgIdx: OptsIdx
): (
...args: {
[P in keyof Args]: OptsIdx extends P
? Args[P] & {
plugins: (PluginObject | string)[];
pluginSearchDirs?: string[];
}
: Args[P];
}
) => Result {
return (...args) => {
const opts = args[optsArgIdx];
args[optsArgIdx] = {
...opts,
plugins: loadPlugins(opts.plugins, opts.pluginSearchDirs)
};
return fn(...args as any);
};
}