Snippets
Creating transparent type-safe typescript wrappers
TS
/**
* A function that wraps the given function argument, returning
* a new function that can be called in place of the original function.
*/
export function wrapper<FArgs extends any[], FReturn>(
fn: (...args: FArgs) => FReturn
) {
// Define the new function to replace the original one.
function newFn(this: any, ...args: Parameters<typeof fn>) {
// Invoke the original function
const result = fn.apply(this, args);
// Return the original function result
return result;
}
// Copy properties from the wrapped function to new function
Object.entries(Object.getOwnPropertyDescriptors(fn)).forEach(
([prop, descriptor]) => {
Object.defineProperty(newFn, prop, descriptor);
}
);
// Return the new function to be used in place of the wrapped function
return newFn;
}
/**
* A function that wraps the given function argument, returning
* a new function that can be called in place of the original function.
*/
export function wrapper<FArgs extends any[], FReturn>(
fn: (...args: FArgs) => FReturn
) {
// Define the new function to replace the original one.
function newFn(this: any, ...args: Parameters<typeof fn>) {
// Invoke the original function
const result = fn.apply(this, args);
// Return the original function result
return result;
}
// Copy properties from the wrapped function to new function
Object.entries(Object.getOwnPropertyDescriptors(fn)).forEach(
([prop, descriptor]) => {
Object.defineProperty(newFn, prop, descriptor);
}
);
// Return the new function to be used in place of the wrapped function
return newFn;
}
Examples
trace
A simple type-safe wrapper to trace the execution of a function
TS
/**
* Traces the execution of the given function, logging its
* arguments and duration.
*/
export function trace<FArgs extends any[], FReturn>(
fn: (...args: FArgs) => FReturn
) {
function newFn(this: any, ...args: FArgs) {
const tag = `${fn.name}(${args}) | duration`;
console.time(tag);
const result = fn.apply(this, args);
console.timeEnd(tag);
return result;
}
Object.entries(Object.getOwnPropertyDescriptors(fn)).forEach(
([prop, descriptor]) => {
Object.defineProperty(newFn, prop, descriptor);
}
);
return newFn;
}
/**
* Traces the execution of the given function, logging its
* arguments and duration.
*/
export function trace<FArgs extends any[], FReturn>(
fn: (...args: FArgs) => FReturn
) {
function newFn(this: any, ...args: FArgs) {
const tag = `${fn.name}(${args}) | duration`;
console.time(tag);
const result = fn.apply(this, args);
console.timeEnd(tag);
return result;
}
Object.entries(Object.getOwnPropertyDescriptors(fn)).forEach(
([prop, descriptor]) => {
Object.defineProperty(newFn, prop, descriptor);
}
);
return newFn;
}