输入一个通用的包装函数来充当记录器?
Typing a generic wrapper function to act as a logger?
我有一个包装任何函数的通用 JS 函数,这样当包装器被调用时,它将执行包装函数,记录事件(函数的输入和输出)然后 return 输出,导致 "transparent" 记录。我的问题是尝试将此函数移动到 TS 并保存包装函数和输出的类型信息被证明有点复杂。
这是我目前所在的位置:
const syncLogger = <T>(f: T) => (...args: unknown[]): ReturnType<T> => {
let value;
try {
value = f(...args);
functionLogger('info', f, value, ...args); // actual logging
} catch (error) {
functionLogger('error', f, error.message, ...args); //actual logging
throw error;
}
return value;
};
它应该是这样使用的:
const myLoggedFunction = syncLogger(originalFunction);
主要问题在于args
,我曾经用作函数输入的n个参数列表:我看不出有什么办法让TS知道这些参数与要包装的原始功能。
我会在参数元组 A
和函数的 return 类型 R
中使 syncLogger
通用,如下所示:
const syncLogger = <A extends any[], R>(f: (...a: A) => R) => (
...args: A
): R => {
let value;
try {
value = f(...args);
functionLogger("info", f, value, ...args); // actual logging
} catch (error) {
functionLogger("error", f, error.message, ...args); //actual logging
throw error;
}
return value;
};
这应该会如您所愿:
function originalFunction(x: string, y: number): boolean {
return (x <= y.toFixed())
}
const myLoggedFunction = syncLogger(originalFunction); // okay
// const myLoggedFunction: (x: string, y: number) => boolean
const bool = myLoggedFunction("121", 123); // info, originalFunction, true, "121", 123
console.log(bool) // true
事实上,在许多情况下,即使原始函数本身是通用的,这也会起作用,因为在 TypeScript 3.4 中添加了对 inferring higher-order function types:
的支持
const loggingItself = syncLogger(syncLogger);
// TS3.3-:
// const loggingItself: (...args: any[]) => (...args: any[]) => {}
// TS3.4+:
// const loggingItself: <A extends any[], R>(f: (...a: A) => R) => (...args: A) => R
无论如何,希望对您有所帮助。祝你好运!
我有一个包装任何函数的通用 JS 函数,这样当包装器被调用时,它将执行包装函数,记录事件(函数的输入和输出)然后 return 输出,导致 "transparent" 记录。我的问题是尝试将此函数移动到 TS 并保存包装函数和输出的类型信息被证明有点复杂。
这是我目前所在的位置:
const syncLogger = <T>(f: T) => (...args: unknown[]): ReturnType<T> => {
let value;
try {
value = f(...args);
functionLogger('info', f, value, ...args); // actual logging
} catch (error) {
functionLogger('error', f, error.message, ...args); //actual logging
throw error;
}
return value;
};
它应该是这样使用的:
const myLoggedFunction = syncLogger(originalFunction);
主要问题在于args
,我曾经用作函数输入的n个参数列表:我看不出有什么办法让TS知道这些参数与要包装的原始功能。
我会在参数元组 A
和函数的 return 类型 R
中使 syncLogger
通用,如下所示:
const syncLogger = <A extends any[], R>(f: (...a: A) => R) => (
...args: A
): R => {
let value;
try {
value = f(...args);
functionLogger("info", f, value, ...args); // actual logging
} catch (error) {
functionLogger("error", f, error.message, ...args); //actual logging
throw error;
}
return value;
};
这应该会如您所愿:
function originalFunction(x: string, y: number): boolean {
return (x <= y.toFixed())
}
const myLoggedFunction = syncLogger(originalFunction); // okay
// const myLoggedFunction: (x: string, y: number) => boolean
const bool = myLoggedFunction("121", 123); // info, originalFunction, true, "121", 123
console.log(bool) // true
事实上,在许多情况下,即使原始函数本身是通用的,这也会起作用,因为在 TypeScript 3.4 中添加了对 inferring higher-order function types:
的支持const loggingItself = syncLogger(syncLogger);
// TS3.3-:
// const loggingItself: (...args: any[]) => (...args: any[]) => {}
// TS3.4+:
// const loggingItself: <A extends any[], R>(f: (...a: A) => R) => (...args: A) => R
无论如何,希望对您有所帮助。祝你好运!