typescript - 在打字稿中,是否可以为 Function.prototype.bind polyfill 正确定义类型?
问题描述
我需要为 Function.prototype.bind 实现一个 polyfill,类似于以下内容:
function functionBind(fn, scope, ...bindArgs) {
return function (...args) {
const boundArgs = bindArgs || [];
const callerArgs = Array.prototype.slice.call(arguments) || [];
return fn.apply(scope, boundArgs.concat(callerArgs));
};
}
但是,我很难为此实现正确的类型。最后,我需要将给定函数的参数作为元组的东西,并且从那个元组中,我需要一个在开头丢失一些条目的类型(取决于为绑定函数提供了多少参数),为结果函数返回正确的类型。
有没有办法得到像部分元组这样的东西?甚至可以正确键入此函数,尤其是在启用所有严格的编译器选项的情况下?
解决方案
没有从元组中取出项目的好方法(有递归条件类型解决方案,但我不一定会使用它们)。bind
打字稿(打开时)的工作方式--strictBindCallApply
是有几个重载,最多可以绑定多个参数:
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 functionBind<T>(fn: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
function functionBind<T, A0, A extends any[], R>(fn: (this: T, arg0: A0, ...args: A) => R, scope: T, arg0: A0): (...args: A) => R;
function functionBind<T, A0, A1, A extends any[], R>(fn: (this: T, arg0: A0, arg1: A1, ...args: A) => R, scope: T, arg0: A0, arg1: A1): (...args: A) => R;
function functionBind<T, A0, A1, A2, A extends any[], R>(fn: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, scope: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
function functionBind<T, A0, A1, A2, A3, A extends any[], R>(fn: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, scope: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
function functionBind<T, AX, R>(fn: (this: T, ...args: AX[]) => R, scope: T, ...args: AX[]): (...args: AX[]) => R;
function functionBind<T>(fn: (this: T, ...args: any[]) => any, scope: T, ...bindArgs: any[]) {
return function (...args: any[]) {
const boundArgs = bindArgs || [];
const callerArgs = Array.prototype.slice.call(arguments) || [];
return fn.apply(scope, boundArgs.concat(callerArgs));
};
}
function test(a: string, b: number) {
}
var r = functionBind(test, null, "") // (b: number) => void
推荐阅读
- html - 为什么当我使用@media 时我的元素不显示?
- python - Pandas 数据框 Timedelta 格式:带天数或带累积小时数
- command-line - 如何在我的世界锻造中打开命令行?另外,如何执行 -Dcofh.rf.crashOnOldAPI=false 命令?
- assembly - 有没有什么有效的方法可以将 Z3 转换成汇编代码?
- android - MutableLiveData 可以有一个子类作为它的类型吗?
- mysql - 需要从项目表中获取所有项目,包括所有提供的标签 ID WITH SEQUELIZE
- python - 循环在装饰器中如何工作(记忆)
- c++ - 在访问 struct 的不同属性的 C++ 函数中重用代码
- cucumber - 在 HTML 编辑器中插入文本
- python - 如何使用 selenium 抓取 Whatsapp 网页的元素