Skip to content

wrong type inference in Promise #31266

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

Closed
dislido opened this issue May 6, 2019 · 6 comments · Fixed by #56908
Closed

wrong type inference in Promise #31266

dislido opened this issue May 6, 2019 · 6 comments · Fixed by #56908
Labels
Duplicate An existing issue was already created

Comments

@dislido
Copy link

dislido commented May 6, 2019

TypeScript Version: 3.4.3

Search Terms:

Code

let foo: string | undefined;
if (!foo) foo = 'hello';

foo.length; // ok

new Promise(resolve => resolve(foo.length));
//                              ^ should be string, but inferred as string | undefined

Expected behavior:

Actual behavior:

Playground Link:

Related Issues:

@GongT
Copy link

GongT commented May 6, 2019

No, that is not ok: foo.length -> [Object is possibly 'undefined']

@lll000111
Copy link

@GongT You mean the 3rd line? There is no error in the playground, with all optional checks enabled.

@j-oliveras
Copy link
Contributor

Most likely, related to #9998.

@weswigham weswigham added the Duplicate An existing issue was already created label May 8, 2019
@weswigham
Copy link
Member

Yep, see #9998 - we cutoff control flow analysis on function boundaries (mostly), so foo only has it's declared type within the Promise callback. If you capture the narrowed value with a const before the callback is made, that'll capture the narrowed value.

@fatcerberus
Copy link

we cutoff control flow analysis on function boundaries (mostly)

Which makes perfect sense, because in general the compiler can't know when a function will be called--or even how many times. In the specific case of Promise we know the function will be called only once, and immediately--but this isn't an assumption the compiler can make in the general case.

@dislido
Copy link
Author

dislido commented May 9, 2019

let foo: string | undefined;
if (!foo) foo = 'hello';

new Promise(resolve => resolve(foo!.length));

ok,It seems that it is the correct solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants