Skip to content

Unable to use done property of IteratorResult to narrow types in typescript 3.6.2 #33241

Closed
@brainkim

Description

@brainkim

TypeScript Version: 3.6.2

Search Terms:
async iterator IteratorResult iterable next return throw type narrowing

Code
file: iterator-result.ts

declare const result: IteratorResult<string, number>;
if (!result.done) {
  let value: string = result.value;
  console.log(value);
}

Expected behavior:
The code compiles. Checking the negation of result.done narrows the type of result.value to string.

Actual behavior:

iterator-result.ts(3,7): error TS2322: Type 'string | number' is not assignable to type 'string'.
  Type 'number' is not assignable to type 'string'.

I thought the whole point of strictly typed iterators was that we could use the done to narrow the type of value, but it seems like a late-game change (making IteratorYieldResult.done optional) prevents us from doing this.

I’m fine with having result.done be optional for IteratorYieldResult but this raises the question why we didn’t also allow result.value to be optional in IteratorReturnResult, when it is idiomatic javascript to return { done: true } without a value in custom iterators.

Playground Link:

Typescript 3.6.2 is not available in the playground yet.

Related Issues:
#30790 <- pr which introduced this change.
#2983
#10564
#11375
#27059

Metadata

Metadata

Assignees

Labels

Design LimitationConstraints of the existing architecture prevent this from being fixedWorking as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions