[英]TypeScript wrapper function with additional parameters
我想为 TypeScript 中现有的 function 创建一个包装器 function。
包装器 function 可以启动一些其他进程,并在完成传递给包装器的主要(“回调”)function 后清理它。
这可以使用此处所示的方法来完成。 但是,这些解决方案不允许我指定可以传递给包装器本身的其他选项。
我将如何 go 这样做?
我的出发点是:
export const wrap = async <T>(
callback: () => T | Promise<T>,
options?: { foo?: string | undefined },
): Promise<T> => {
let ret;
// begin
if (options.foo) {
// do something
}
try {
ret = await callback();
} catch (e) {
throw e;
} finally {
// cleanup
}
return ret;
};
这不会让我将 arguments 添加到callback()
。 我可以使用...args
,但如何同时指定...args
和options
?
我建议你把你的 function 写成一个工厂(返回另一个函数的函数):
function wrap<T extends (...args: any[]) => any>(callback: T, options?: { foo?: string | undefined }): (...args: Parameters<T>) => ReturnType<T> extends Promise<infer U> ? Promise<U> : Promise<ReturnType<T>>
function wrap(callback: (...args: any[]) => any, options?: { foo?: string | undefined }): (...args: any[]) => Promise<any> {
return async function (...args: any[]) {
let ret;
// begin
if (options && options.foo) {
// do something
}
try {
ret = await callback(...args);
} catch (e) {
throw e;
} finally {
// cleanup
}
return ret;
}
};
async function asyncExtractFirstParameter(str: string, num: number, bool: boolean) {
return str;
}
function extractFirstParameter(str: string, num: number, bool: boolean) {
return str;
}
const wrappedAsyncExtractFirstParameter = wrap(asyncExtractFirstParameter);
const wrappedExtractFirstParameter = wrap(extractFirstParameter);
wrappedAsyncExtractFirstParameter('test', 23, true).then(console.log);
wrappedExtractFirstParameter('test', 23, true).then(console.log);
这允许您创建另一个 function 与回调具有相同的签名,并可能推迟其执行。
该解决方案包括使函数通用 ( F
) 并通过ReturnType
和Parameters
推断该 function 的参数和返回类型。 可以在传递给callback
function 的解构剩余 arguments 之前指定任何其他选项:
export const wrap = async <F extends (...args: any[]) => ReturnType<F> | Promise<ReturnType<F>>>(
callback: F,
options: { foo?: string | undefined } = {},
...args: Parameters<F>
): Promise<ReturnType<F>> => {
let ret: ReturnType<F> | undefined;
// begin
if (options.foo) {
// do something
}
try {
ret = await callback(...args);
} catch (e) {
throw e;
} finally {
// cleanup
}
return ret;
};
然后可以像这样调用包装器:
const someFunction = (arg1: string, arg2: boolean): void => {
// do something
}
wrap(someFunction, { foo: "yes" }, arg1, arg2)`
所有返回类型和参数类型都是自动推断的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.