Repository: TypeScript
Issue: generator next type should be inferred as union (instead of intersection) of yields' types OR just unknown
Labels: Needs Investigation

### 🔎 Search Terms

generator
yield
next

### 🕗 Version & Regression Information

- This is the behavior in every version I tried, and I reviewed the FAQ for entries about generators


### ⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.0-beta&filetype=ts#code/GYVwdgxgLglg9mAVAAgOYFMzoE4EMpzYAUAlMgN4BQyyECAzlMgJ4zoA2AJgIwBcyjbDDCpkAXhZsu1Wgzjt0AOnZxURcpI49kAXxIy6YRpq4AmfmBABbAEY5xJzgbkLlq9Y9O79NQ8dZaAMz8NnDy6LhgDgHSvi5KKmoaMZyB3pQ6lJR+TBhREnk4+ISklHmKWAAeUKVlmBXo1UQA5ILCqM1kAPRdyAAqzAAO6MitUEIizcgw9MhgcEy49PQwqGC4NgrIBNtDI81YAG44zZQ9FI58o22TunVgDU2m3b0Dw6OWtifTs-OLy6t1psRjsoHsPuhjthTudklJOOZkF5MuUqjVxiB0C9+uDmqFwpEpjM5gtkEsVmsNltQbijiczr04UF+BiRpkgA

### 💻 Code

the following is perfectly valid javascript
```js
function* generator() {
  const yield1 = yield
  console.log({ yield1 })
  const yield2 = yield
  console.log({ yield2 })
  const yield3 = yield
  console.log({ yield3 })
}

const gen = generator()
gen.next()

gen.next('string')
// { yield1: 'string' }
gen.next(2)
// { yield2: 2 }
gen.next(true)
// { yield3: true }
```

but becomes a type error when converted to the equivalent typescript
```ts
function* generator() {
  const yield1: string = yield
  console.log({ yield1 })
  const yield2: number = yield
  console.log({ yield2 })
  const yield3: boolean = yield
  console.log({ yield3 })
}

const gen = generator()
gen.next()

gen.next('string') // Type 'string' is not assignable to type 'never'
// { yield1: 'string' }
gen.next(2) // Type 'number' is not assignable to type 'never'
// { yield2: 2 }
gen.next(true) // Type 'boolean' is not assignable to type 'never'
// { yield3: true }
```


### 🙁 Actual behavior

`generator`'s inferred type signature is
```
function generator(): Generator<undefined, void, never>
```
because the [`Generator`'s `TNext`](https://github.com/microsoft/TypeScript/blob/ebcb09d71a0838b4b9be974f9ef1e80fce8888af/src/lib/es2015.generator.d.ts#L3) gets inferred as the _intersection_ of the `yield`s' types: `string & number & boolean` -> `never`

### 🙂 Expected behavior

`generator`'s inferred type signature should be the _union_ of the `yield`s' types
```
function generator(): Generator<undefined, void, string | number | boolean>
```

OR

just `unknown`
```
function generator(): Generator<undefined, void, unknown>
```
causing `(yield) as string` (along with the usage of any type to which `unknown` is not assignable) to be a compilation error

### Additional information about the issue

while inferring the union still isn't perfectly type-safe (e.g. the inferred union cannot statically prevent a `const yield1: string = yield` from being incorrectly called with `next(2)`), it would go beyond bringing the inferred version up to parity with the explicit version because the explicit version would not be able to type each `yield` independently:
- this is a type error
  ```ts
  function* generator(): Generator<undefined, void, string | number | boolean> {
    const yield1: string = yield // Type 'number' is not assignable to type 'string'
    console.log({ yield1 })
    const yield2: number = yield // Type 'string' is not assignable to type 'number'
    console.log({ yield2 })
    const yield3: boolean = yield // Type 'string' is not assignable to type 'boolean'
    console.log({ yield3 })
  }
  ```
- this loses type precision
  ```ts
  function* generator(): Generator<undefined, void, string | number | boolean> {
    const yield1 = yield // string | number | boolean
    console.log({ yield1 })
    const yield2 = yield // string | number | boolean
    console.log({ yield2 })
    const yield3 = yield // string | number | boolean
    console.log({ yield3 })
  }
  ```
  - forcing each `yield` to be typed as the intersection of all `yield`s' _respective_ (desired) type may in fact be desirable because
    > the inferred union cannot statically prevent a `const yield1: string = yield` from being incorrectly called with `next(2)`

    but if this is the case, perhaps generators should _never_ have their types inferred and instead default to all `TNext`s/`yield`s being typed as `unknown`, thereby prompting the developer to provide their explicit types when more precision is needed. this would also promote safer `yield` consumption, e.g.
    ```ts
    /** inferred as `Generator<undefined, void, unknown>` */
    function* generator() {
      const yield1: string = yield // Type 'unknown' is not assignable to type 'string'
      const yield2: number = yield // Type 'unknown' is not assignable to type 'number'
      const yield3: boolean = yield // Type 'unknown' is not assignable to type 'boolean'
    }
    ```
    prompts the developer to rewrite it as
    ```ts
    /** inferred as `Generator<undefined, void, unknown>` */
    function* generator() {
      const yield1 = yield // unknown
      if (typeof yield1 != 'string') throw new Error
      const yield2 = yield // unknown
      if (typeof yield2 != 'number') throw new Error
      const yield3 = yield // unknown
      if (typeof yield3 != 'boolean') throw new Error
    }
    ```
    and eventually
    ```ts
    function* generator(): Generator<undefined, void, string | number | boolean> {
      const yield1 = yield // string | number | boolean
      if (typeof yield1 != 'string') throw new Error
      const yield2 = yield // string | number | boolean
      if (typeof yield2 != 'number') throw new Error
      const yield3 = yield // string | number | boolean
      if (typeof yield3 != 'boolean') throw new Error
    }
    ```