Typescript: Function.prototype.bind method seems to confuse the compiler

Created on 21 Jun 2017  ·  4Comments  ·  Source: microsoft/TypeScript



I recently upgraded from _2.2.1_ to _2.3.1_ version and suddnely I get a compiling error, which I wouldn't expect at all. Please see code example, and also you can see the error in Typescript playground, http://bit.ly/2rBt43G

TypeScript Version: 2.3.1 / "lib": ["es2015"]

Code

interface Person { 
    name: string;
    age: number;
}

function doSomething(): string {
    return 'something';
}

function doPromise(): Promise<Person> { 
    return new Promise(resolve => setTimeout(_ => resolve({ name: 'Fran', age: 38 }), 2000));
}

// No problem here
function doAsyncStuff(): Promise<string> { 
    return doPromise()
        .then(_ => doSomething())
}

// No problem here
function doAsyncStuff2(): Promise<string> { 
    return doPromise()
        .then(doSomething)
}

/**
 * Compiler complains:
 * Type 'Promise<Person>' is not assignable to type 'Promise<string>'
 */
function doAsyncStuff3(): Promise<string> { 
    return doPromise()
        .then(doSomething.bind(null))
}

Expected behavior:
I would expect the compiler to infer the type of the function returned by "_bind_" function

Actual behavior:
It expects the type of the promise returned by "_doPromise_"

Thanks a lot

Question

Most helpful comment

This could be an instance of #212 and is hard to solve well without something like type operators over the tuples corresponding to parameter lists (as in #5453). As a workaround for your specific issue you could add a declaration like:

interface Function {
  bind<F extends Function>(this: F, thisArg: any): F
}

since you're not passing any initial arguments to the function being bound.

All 4 comments

This could be an instance of #212 and is hard to solve well without something like type operators over the tuples corresponding to parameter lists (as in #5453). As a workaround for your specific issue you could add a declaration like:

interface Function {
  bind<F extends Function>(this: F, thisArg: any): F
}

since you're not passing any initial arguments to the function being bound.

I'm not sure why you're only seeing this in 2.3.1 - I guess we're not making correct inferences from the onfulfilled argument to then when any is passed in.

In any case, there's definitely a limitation from #212. From both a performance type-safety perspective, you're better off using arrow functions instead of bind, call, and apply.

Thanks guys for the answer. Eventually I went for the arrow function as suggested by @DanielRosenwasser

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

weswigham picture weswigham  ·  3Comments

fwanicka picture fwanicka  ·  3Comments

siddjain picture siddjain  ·  3Comments

seanzer picture seanzer  ·  3Comments

jbondc picture jbondc  ·  3Comments