Description
Bug Report
I was creating a coroutine-based interactive prompt library. It can consume either synchronous or asynchronous co-routines.
There doesn't seem to be any runtime issue associated with this approach, (in some configurations the library harmlessly awaits on a synchronous generator.next()).
However, any function which is declared as fulfilling a union of async+sync generators faces a compile error when a spurious undefined
value is indicated as possible from a yield
even though the next() call only accepts strings.
🔎 Search Terms
yield, undefined, typescript, asyncgenerator, generator
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about AsyncGenerator
⏯ Playground Link
Playground link with relevant code
💻 Code
type SyncSequenceFactory = () => Generator<string, string, string>;
type AsyncSequenceFactory = () => AsyncGenerator<string, string, string>;
type SequenceFactory = SyncSequenceFactory | AsyncSequenceFactory
const syncFactory: SyncSequenceFactory = function* (){
let name = "";
while(!name){
name = yield "What is your name?"
}
return `That's the end of the game, ${name}`
}
const asyncFactory: AsyncSequenceFactory = async function* (){
let name = "";
while(!name){
name = yield "What is your name?"
}
return `That's the end of the game, ${name}`
}
const looserSyncFactory: SequenceFactory = function* (){
let name = "";
while(!name){
name = yield "What is your name?"
}
return `That's the end of the game, ${name}`
}
const looserAsyncFactory: SequenceFactory = async function* (){
let name = "";
while(!name){
name = yield "What is your name?"
}
return `That's the end of the game, ${name}`
}
🙁 Actual behavior
Compiler reports Type 'string | undefined' is not assignable to type 'string'.
🙂 Expected behavior
I don't believe this possible execution path is actually made possible by the union, since it is not possible in either of the unioned cases.