当使用四个以上参数时,Typescript .bind()给出类型错误

时间:2019-07-17 09:11:41

标签: javascript typescript

使用打字稿3.5.2,我遇到了与.bind()相关的问题。

我试图用一些初始参数绑定一个函数。

async foo(arg1: any,
    arg2: any,
    arg3: any,
    arg4: any,
    arg5: any,
    arg6: any,
    arg7: any) {
    //some fancy tasks
}

我正在尝试将功能与上下文和一些初始参数绑定。

private buildHandler(arg1: Function, arg2: IReplaceSet[], arg3: IReplaceSet[] = [], arg4: IReplaceAsset[] = [], arg5: boolean) {
    return this.foo.bind(this, arg1, arg2, arg3, arg4, arg5);
}

Typescript将.bind解析为这种类型。

bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;

错误编译器给出:

  

返回this.foo.bind(this,arg1,(错误)arg2,arg3,arg4,arg5);

     

错误:(401,64)TS2345:类型“ any”的参数无法分配给类型“ Function”的参数。     类型“ IReplaceSet []”缺少类型“功能”的以下属性:应用,调用,绑定,原型以及另外4个。


编辑1: 每当我从绑定错误修复程序中删除所有这些初始参数时

return this.foo.bind(this, arg1, arg2, arg3, ag4);

为什么对打字稿.bind()定义有参数限制?因为它与类型匹配

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;

Edit2: 传播也可以解决问题,但是为什么呢?

return this.foo.bind(this, ...[arg1, arg2, arg3, arg4, arg5]);

Edit3: 现在,我认为这是一个与打字稿有关的问题,我已经解决了该问题。我将对此回答,因为这是一个重要的问题。

1 个答案:

答案 0 :(得分:1)

使用CallableFunction方法的Typescript bind接口最多支持4个具有唯一类型定义的参数。

interface CallableFunction extends 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, th
isArg: 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;
}

您会看到bind(context, arg1, arg2, arg3, arg4)受以下类型支持:

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;

并且该类型期望所有初始参数均为通用类型AX,这意味着:您将使用的所有参数应与第一个参数具有相同的类型。举个例子:

这将给出错误。因为arg4的类型与arg1不同

arg1: string;
arg2: string;
arg3: string;
arg4: number;
arg5: string;
arg6: string;
bind(context, arg1, arg2, arg3, arg4, arg5, arg6);

Spreading解决了我的问题,因为Spreading在Typescript上还没有任何类型定义。

我希望它对其他人也有帮助。