使用绑定函数柯里化并在 TypeScript 中使用泛型正确键入
Currying with bind function and to correctly type with generic in TypeScript
我写了一个排序函数,想给它绑定一个比较函数。不幸的是,TypeScript 编译器警告我比较函数的 unknown
类型。
我试过搜索 SO: Bind function to function
并在 TS Handbook: bind 中搜索。但是,我找不到任何相关问题。
并尝试遵循声明文件中的类型:
/**
* For a given function, creates a bound function that has the same body as the original function.
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
* @param thisArg The object to be used as the this object.
* @param args Arguments to bind to the parameters of the function.
*/
bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;
bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;
bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;
function sorting<T>(a: T, fn: (v0: T, v1: T) => number, b: T) {
return fn(a, b)
}
sorting<number>.bind(null, 1, (a, b) => a + b)
// ^ Cannot find name 'bind'.(2304)
sorting.bind<null, number, (v0: number, v1: number) => number, [b: number]>(null, 1, (a, b) => a + b)
//^ Argument of type '(b: number) => unknown' is not assignable to parameter of type //'(v0: number, v1: number) => number'.
// Type 'unknown' is not assignable to type 'number'.(2345)
而且还是不行。我在这里错过了什么吗?为什么我不能 bind
参数 a
和 fn
?
P.S.
目前我使用箭头函数柯里化排序函数作为变通方法。
这实际上是一个常见问题,而且非常常见,将在下一个次要版本的 TypeScript (4.7) 中修复!正在使用的解决方案称为 instantiation expression.
这是他们的例子:
interface Box<T> {
value: T;
}
function makeBox<T>(value: T) {
return { value };
}
虽然你可以这样做:
const makeStringBox = (value: string) => makeBox(value); // makeBox<string>(value: string)
相当浪费,所以4.7引入了新的语法:
const makeStringBox = makeBox<string>; // type parameters passed without calling it!
这也意味着您可以在绑定之前将其传递给 sorting
:
// works in 4.7+ now!
sorting<number>.bind(null, 1, (a, b) => a + b)
您可以试试夜间版的 TypeScript (4.8+) here with this example.
我写了一个排序函数,想给它绑定一个比较函数。不幸的是,TypeScript 编译器警告我比较函数的 unknown
类型。
我试过搜索 SO: Bind function to function 并在 TS Handbook: bind 中搜索。但是,我找不到任何相关问题。
并尝试遵循声明文件中的类型:
/**
* For a given function, creates a bound function that has the same body as the original function.
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
* @param thisArg The object to be used as the this object.
* @param args Arguments to bind to the parameters of the function.
*/
bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;
bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;
bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;
function sorting<T>(a: T, fn: (v0: T, v1: T) => number, b: T) {
return fn(a, b)
}
sorting<number>.bind(null, 1, (a, b) => a + b)
// ^ Cannot find name 'bind'.(2304)
sorting.bind<null, number, (v0: number, v1: number) => number, [b: number]>(null, 1, (a, b) => a + b)
//^ Argument of type '(b: number) => unknown' is not assignable to parameter of type //'(v0: number, v1: number) => number'.
// Type 'unknown' is not assignable to type 'number'.(2345)
而且还是不行。我在这里错过了什么吗?为什么我不能 bind
参数 a
和 fn
?
P.S.
目前我使用箭头函数柯里化排序函数作为变通方法。
这实际上是一个常见问题,而且非常常见,将在下一个次要版本的 TypeScript (4.7) 中修复!正在使用的解决方案称为 instantiation expression.
这是他们的例子:
interface Box<T> {
value: T;
}
function makeBox<T>(value: T) {
return { value };
}
虽然你可以这样做:
const makeStringBox = (value: string) => makeBox(value); // makeBox<string>(value: string)
相当浪费,所以4.7引入了新的语法:
const makeStringBox = makeBox<string>; // type parameters passed without calling it!
这也意味着您可以在绑定之前将其传递给 sorting
:
// works in 4.7+ now!
sorting<number>.bind(null, 1, (a, b) => a + b)
您可以试试夜间版的 TypeScript (4.8+) here with this example.