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

Adjust Type guard behavior in iterators #29916

Closed
5 tasks done
crymis opened this issue Feb 14, 2019 · 4 comments · Fixed by #56908
Closed
5 tasks done

Adjust Type guard behavior in iterators #29916

crymis opened this issue Feb 14, 2019 · 4 comments · Fixed by #56908
Labels
Duplicate An existing issue was already created

Comments

@crymis
Copy link

crymis commented Feb 14, 2019

TypeScript Version: 3.2.2

Search Terms: Conditional Types, Type Guards, iterators, loop, callback functions

Suggestion:
When having values that are of union type and conditions result in telling the Typescript Type Guards to adjust the type, in basic Javascript iterator functions this adjusted type is reset to its initial type.

Code Example:

const myFunc = () => {
  let myVal: string | undefined;
  if (!myVal) return;
  myVal; // Type = string
  new Array(2).forEach(x => myVal); // Type = string | undefined
}

Expected behavior:
The type of myVal in the last line should only be of type string.
This would be nice for all iterators (e.g. for, while, map, …)

Actual behavior:
The type of myVal is string | undefined

Playground Link:
https://www.typescriptlang.org/play/#src=const%20myFunc%20%3D%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20let%20myVal%3A%20string%20%7C%20undefined%3B%0D%0A%20%20%20%20if%20(!myVal)%20return%3B%0D%0A%20%20%20%20myVal%3B%20%2F%2F%20Typ%20%3D%20string%0D%0A%20%20%20%20new%20Array(2).forEach(x%20%3D%3E%20myVal)%3B%20%2F%2F%20Typ%20%3D%20string%20%7C%20undefined%0D%0A%7D

Info:
I don't know why, but the playground does not show the correct typing, please test in your code.

Checklist:
My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@nmain
Copy link

nmain commented Feb 14, 2019

I don't know why, but the playground does not show the correct typing, please test in your code.

You need to enable strictNullChecks in the options on the playground to see your issue reproduced there.

@j-oliveras
Copy link
Contributor

Same as #29805 and duplicated/related to #9998.

Basically, typescript don't know if the predicate on forEach is called synchronously or not.

Workaround:

const myFunc = () => {
  let myVal: string | undefined;
  if (!myVal) return;
  const v =  myVal; // Type = string
  new Array(2).forEach(x => v); // Type = string
}

Playground (enable strictNullChecks).

@crymis
Copy link
Author

crymis commented Feb 15, 2019

Thank you @j-oliveras for pointing the relations.

I read about the workaround with the const declaration, thanks for that.

My feature-request here is to add logic for basic Javascript iterators. So, if it is a standard callback-function (not overwritten), then you could teach Typescript that these functions run synchronously, right?

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Feb 19, 2019
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

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.

5 participants