高阶函数(HOF)的类型定义一直是 TypeScript 里面相对难度比较高的地方, 而且容易忘记, 所以我打算在这里做一个备忘, 记录一下自己找到或者实现的一些定义
接受的函数和返回的函数的参数一致
const beforeFn =
<F extends (...args: any[]) => any>(fn: F) => (...args: Parameters<F>): ReturnType<F> => {
console.log('before function:', fn.name);
return fn(...args);
};
const sum = (a: number, b: number) => a + b;
const beforeSum = beforeFn(sum);
// declare const beforeSum: (a: number, b: number) => number;
返回的函数比接受的函数多一个参数
From: https://blog.openreplay.com/forever-functional-higher-order-functions-with-typescript/
const demethodize =
<
O extends {name: string},
T extends (...args: any[]) => any
>(fn: T) =>
(arg0: O, ...args: Parameters<T>): ReturnType<T> =>
fn.bind(arg0, ...args)();
const obj = {
name: 'jack',
sayHi(question: string) {
console.log(`Hi, I'm ${this.name}! And ${question}`);
}
};
const sayHiBySomeOneWithQuestion = demethodize(obj.sayHi);
// declare const sayHiBySomeOneWithQuestion: (arg0: {
// name: string;
// }, question: string) => void;
返回的函数和接受的函数的只有第一位不一样
interface Rect {}
interface Instance {
getRect(): Rect;
}
type DropFirst<T extends unknown[]> = T extends [any, ...infer U] ? U : never
function withInst<
F extends (arg0: Rect, ...args: any[]) => any,
>(fn: F) {
return (i: Instance, ...args: DropFirst<Parameters<F>>): ReturnType<F> => {
const r = i.getRect();
return fn(r, ...args) as ReturnType<F>;
};
}
const setRectX = (r: Rect, x: number) => {}
const copyRect = (r: Rect, c: Rect) => {}
const setInstX = withInst(setRectX); // declare const setInstX: (i: Instance, x: number) => void;
const copyRectToInst = withInst(copyRect); // declare const copyRectToInst: (i: Instance, c: Rect) => void;
原创内容,欢迎转载 😊