This suggestion has a few pieces: 1. Implement boolean literal types for `true` and `false`, in a fashion similar to #1003 2. Implement type guards for booleans. Essentially, control flow constructs like if-else, while, for, etc would be subject to a type guard if their guard expression is a boolean. 3. Now we can update generators to have a `next` method that returns `{ done: false; value: TYield; } | { done: true; value: TReturn; }`, where TYield is inferred from the yield expressions of a generator, and TReturn is inferred from the return expressions of a generator. 4. Iterators would return `{ done: false; value: TYield; } | { done: true; value: any; }` to be compatible with generators. 5. for-of, spread, array destructuring, and the type yielded by `yield*` would only pick the value associated with done being false. 6. The value of a `yield*` expression would pick the value associated with done being true. 7. Introduce a Generator type that can be used to track the desired type of a `yield` expression. This would be TNext, and would be the type of the parameter for the next method on a generator. The generator type would look something like this: ``` ts interface Generator<TYield, TReturn, TNext> extends IterableIterator<TYield> { next(value?: TNext): IteratorYieldResult<TYield> | IteratorReturnResult<TReturn>; throw(exception: any): IteratorYieldResult<TYield> | IteratorReturnResult<TReturn>; return(value: any): IteratorYieldResult<TYield> | IteratorReturnResult<TReturn>; [Symbol.iterator](): Generator<TYield, TReturn, TNext>; [Symbol.toStringTag]: string; } ```