Please your library user with typescript generic
In typescript, generic is a tool that api/library author to please its consumer. What does this means.
For example, as library developer, I want to create a higher order function to modify a an existing function, so that I can log the entering and exiting of the function 's execution. The following function does the job
function log (fn) { const name = fn.name; return function (...args) { console.log(`entering ${name}`); const rtn = fn(...args); console.log(`leaving ${name}`); }; } function add(a:number, b: number) { return a + b; } add(1, 2); add('1', '2'); //warning // const logAdd = log(add); //type information is lost logAdd(1, 2); logAdd('1', '2'); //no warning
When consuming the log function, the modified function run as expected, but it lost the signature of the original function, and it cannot type checking like the original function.
It is pretty easy to solve the problem by adding generic to the log function.
function log<T extends (...args) => any>(fn: T) { const name = fn.name; return function (...args) { console.log(`entering ${name}`); const rtn = fn(...args); console.log(`leaving ${name}`); } as T; } function add(a:number, b: number) { return a + b; } add(1, 2); add('1', '2'); //warning // const logAdd = log(add); //type information is retained. logAdd(1, 2); logAdd('1', '2'); //warning
Now the modified function has all the type information of the original function. The way it works is that typescript infer the type of input argument, and pass along the type along.