Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function.prototype.bind method seems to confuse the compiler #16676

Closed
jscriptcoder opened this issue Jun 21, 2017 · 4 comments
Closed

Function.prototype.bind method seems to confuse the compiler #16676

jscriptcoder opened this issue Jun 21, 2017 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@jscriptcoder
Copy link

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

@jcalz
Copy link
Contributor

jcalz commented Jun 21, 2017

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.

@DanielRosenwasser DanielRosenwasser added the Needs Investigation This issue needs a team member to investigate its status. label Jun 21, 2017
@DanielRosenwasser
Copy link
Member

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.

@jscriptcoder
Copy link
Author

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

@mhegazy mhegazy added Question An issue which isn't directly actionable in code and removed Needs Investigation This issue needs a team member to investigate its status. labels Nov 20, 2017
@typescript-bot
Copy link
Collaborator

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

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

5 participants