镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Cannot mix both fixed and rest arguments using '.call' when using '--strictBindCallApply' #37834

Description

@rbuckton

TypeScript Version: 3.9.0-dev.20200328

Search Terms: strict call rest arguments

Code

class C {
    use<A extends any[]>(fn: (this: this, obj: this, ...args: A) => void, ...args: A) {
        fn.bind(this, this)(...args); // ok
        fn.bind(this)(this, ...args); // error
        fn.call(this, this, ...args); // error
    }
}

Expected behavior:

The 2nd and 3rd cases above should be ok

Actual behavior:

The 2nd and 3rd cases above report errors.

Playground Link: Playground

Related Issues:

Activity

  1. rbuckton commented on Apr 8, 2020

    @rbuckton
    ContributorAuthor

    The bind error case is likely a design limitation until we can represent spreading a non-array-type in a tuple type, i.e. [T, ...U] (if U has an array or tuple type as a base constraint).

    We could possibly resolve the call error case by adding a few overloads.

  2. rbuckton commented on Apr 8, 2020

    @rbuckton
    ContributorAuthor

    The bind case could also be partially resolved by specifying a fixed set of unbound type arguments, i.e.:

    bind<T, A0, A extends any[], R>(
      this: (this: T, arg0: A0, ...args: A) => R,
      thisArg: T
    ): (arg0: A0, ...args: A) => R;

    This is similar to the existing bind<T, A0, A extends any[], R> overload, except that it passes on arg0 and allows us to have the fixed argument list.

  3. rbuckton commented on Apr 8, 2020

    @rbuckton
    ContributorAuthor

    Unfortunately, just adding overloads doesn't address this. I added these to call and ended up with cases that should be errors compiling successfully:

        call<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0, ...args: A): R;
        call<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;
        call<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;
        call<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;

    From tests\cases\conformance\functions\strictBindCallApply1.ts:

    declare function foo(a: number, b: string): string;
    ...
    let c03 = foo.call(undefined, 10, "hello", 30);  // Error

    The above call reports an error without the overloads: error TS2554: Expected 3 arguments, but got 4., but with the overloads we infer a function type that has the excess argument A3 and foo is assignable to that type so we don't report an error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs InvestigationThis issue needs a team member to investigate its status.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions