Repository: TypeScript
Issue: Design Meeting Notes, 4/30/2024
Labels: Design Notes


# `TReturn` and `TYield` for Iterators and Other Types

#58243

* `TReturn` is the type of values *returned* by a generator.
* `TYield` is the type of values *yielded* by a generator.
* When we added these, we only added them to certain types like `IteratorResult`
    * Since then, we have a PR that adds type parameters to `Iterator`, `IterableIterator`, `AsyncIterable`, etc.
    * What this has meant since then was that if you ever try to grab `value` off of most `IteratorResult`s, then you'll get `any`.
        * Good as a fall-back, but usually not what people want.
* Changing this is a breaking change - so how can we avoid breaks?
    * First, each of these types should have a default value for `TReturn` and `TYield` that is `any`.
        * But when a user writes `Iterator<number>`, TypeScript should preserve that type as-is.
    * What is the level of breakage as is?
        * Almost every case is an example of the type system not knowing that `size > 0` implies `value` is not `undefined`.
        * There's also a lot of breakage around DefinitelyTyped's `ExpectType` and `ExpectError` utility types.
* Several new errors introduced. Previously, people expecting `.next()` to return a `T` now get `T | void`.
    * e.g. `if (something.size === 1) { something.values().nexT().value.getTasks(); }`
    * Why is it `void` and not `undefined`?
        * Should it be `undefined`?
        * We really don't want to relitigate all the issues around non-returning functions returning `void` instead of `undefined`.
        * It's possible we carve things out for generators.
    * Should we allow postfix `!` to get rid of `void`?
* How many upvotes does resolution for this issue have?
    * Old issue had around 15 upvotes.
    * This is so breaky that most of this has to go under a switch.
* What happens if we don't do this?
    * People trying to thread these into the built-in iterator types.
    * If you have a generator, you can now write `myGenerator().map(x => x * x)` and you want the `TReturn` preserved.
* If the worst thing you have to do is add a `!`, is that so bad?
* Feel like there should be an approach where this is flagged.
    * Could be like `strictBindCallApply`.
    * We fret about breaks for much more widely-requested features.
    * But the people it breaks are using iterators, probably want to use the feature.
    * The flag that this conceptually aligns with is `noUncheckedIndexedAccess`.
        * Ah yes, `.next()`, the famous indexed access syntax.
        * Okay, fine, a separate flag with an equally bad name (`noUncheckedIteratorAccess` or `noUncheckedIteratorResult`).

# `tsc --init` Updates?

* We noticed `tsc --init` adds `"module": "commonjs"` - which our docs said to never ever ever do.
* Okay, what else do we need to fix in `--init`?
* [Ryan asked on Twitter what people would like to change](https://twitter.com/SeaRyanC/status/1782783901213282557).
* People said lots of stuff
    * Big one that resonates: remove the wall of text comments
* Are we okay wiht `tsc --init` generating a file today?
    * Uh yes.
* Okay, that's a good start.
* What else?
    * Make it minimal
    * People seem opposed to interactive.
* Okay, what are things that need to be hashed through?
    * `target: esnext`?
    * `module` - `node16` or `bundler`?
    * `verbatimModuleSyntax`?
    * `skipLibCheck`?
    * We need to hash through these.
* Should we still have *some* comments on defaults?
    * Maybe.
    * [Ryan also wrote a wizard](https://ryancavanaugh.github.io/tsc-init/), someone else wrote something too.