Repository: TypeScript
Issue: `.then(onresolved)`'s return type should not be inferred from contextual type
Labels: Possible Improvement

# lib Update Request


<!--
  Please fill in each section completely. Thank you!

  Are you here for one of these commonly-requested lib changes?
    * Object.keys - see https://stackoverflow.com/questions/55012174/
    * Array methods - see https://github.com/microsoft/TypeScript/issues/36554
    * parseInt, parseFloat, isFinite, isNaN, etc. - see https://github.com/microsoft/TypeScript/issues/4002

  The DOM lib is maintained elsewhere and you can skip a step by filing issues/PRs for the DOM at that repo.
  See https://github.com/microsoft/TypeScript-DOM-lib-generator
-->

## Configuration Check

<!--
  If you're missing common new methods like Array.includes, you may have a misconfigured project.
  Try setting `lib: "es2020"` and checking whether the type you want is present.
  You can diagnose further by running `tsc` with `--listFilesOnly` or `--showConfig`.

  Conversely, if you are seeing built-in methods you expect to *not* see, check your 'lib' setting
  or review your dependencies for lib/reference directives that might be polluting
  your global scope. This is common when using the 'node' type library. See https://github.com/microsoft/TypeScript/issues/40184

  Replace the text below:
-->
My compilation *target* is `ES2015` and my *lib* is `the default`.
> Also reproducible with target ESNext, ES2022 ect. 

## Missing / Incorrect Definition

<!--
  What property, method, function, etc is missing or incorrect?
-->

Promise.prototype.then

## Sample Code

<!--
  What's some code using this that should work, but doesn't?
-->

TypeScript infers the  return type of `then` from the contextual type information when called with only one argument. 
This can cause unexpected results

```typescript
let a: string | undefined
const b = a ?? await somePromise.then(() => "str")
```

I expect  `b` to be `string` because either `a` is a `string`, somePromise resolves and then returns a string, or somePromise rejects and await throws so b is not assigned. 
However `b` is actually `string | undefined` because the contextual type on the RHS of a nullish operator is the type of the LHS
and `then` inferred it's return type from the context because TResult2 was not inferred from arguments.

```typescript
b satisfies string | undefined
```

* [playground](https://www.typescriptlang.org/play?ssl=48&ssc=1&pln=48&pc=11#code/PTAEBUE8AcFMGUDGAnAltALqAzgewLawaqHagCu2sZAhqAG40A251oiuAdhrAB5YZcoVJwBmsZMIwByMhhiwAsACgQoABYYM0bAC4QAdyMA6eXGwp0GJjU4BzY7mR3gAE1yJswdbdcAjXFwAa2AzWABaEXFkWE5EWGNNfCYAYg5uPgxyZnCzETsVFTVyVABRelisVDIoiVhXUBoycsrQP1hEGkpYUFxRUAx1HvSefgAaIrBBntFyOOIuYVpsbFQ7TnqBoS4LZFwmJlADdVREdVBXWFERNjoW7kbnckJuYxUDEXcDR05d-cOALygWbzVCLAAUJXuGAAlKAAN4UMoVB7YGjEbDXNjQ0AAX0KqjAAAlcBVJKSJBoKcgAMJcUYCIRUHqDdEQJbCMR1BpNUCcZ7tcmSbAYND2UAAHwonEu1w2rkmF1gcBl+V6nCOPiqMmWq3WLwwb2U6RFjV0fIFlKB6mpdIy-HBMJUJqwfnNIrFdkl0tlNwa1tt9MyjoJahJZN6EZtZLtDK2OFgLK1AyG7CD-GyhzC6pTPQASkT4L1+tMLQdqudcHBkOinIrqrmcDRCAMFI05KmADKFo0gRUARmMoAAkh2G6WOMgYohXbAfPQwcgAPyK0Br0DhUDwG3kJgNCfp2fSoKcXAGTgrwnrteb7e4Xf71MjTJtHoAOS4b93Nj8TFgAB5u3gAA+S81HXYd2FsBMehoJ4DTIUQnFAWAaDOYtcyoRoZUbRByCnVp2nnRcjToJclypGNDxDZQ-FAcjKIkWNgydZRFXDSlqXYeNmRTNlUCqGouQInkyA9NUpTmX15XYriuNMIYNUEGCpFkTlohiUTQH-cT7DGHBRQkn0rj9YD2LqNS6FWfBoCYVAsQaMlVkWPpQAU2I1LCXtgFXDQtB0fRgDsAT1HIPxjA4fBgHwU49jwUQMGAKA4CQNBMGAX9cD8aKaBEYBsGQRBgDs7LqAAVmMVxTGwFJO37MqACYABZfOmTh-zzah9gqf0IH0zqACsOh4XqNjJYDwV89cuBiPAmB6pdzXBDBzXAOEAWA0BOrmnqJiva91RiIaZ3qRbQEdUANq22BjpGvbwNAGFzQABT2GKqA6rr5s2KVBo6eozMJRUP2IeI+KwP6ToaAxeVqET2wMz1vSkkz5U1VA-ykI5eVPLBulce6wF5AwencThpCwaA9gXS5Dpu4b6iHSDBhEIJGxiLJkA1RgWB6Bs4c04E3sbAt4EVVz+XLbBK2rWtkG866ds2fnhMF3ldK9URhdLbNXIAA3oS7NvoPW2nIARUw171tu65XsEVOZZttho8AgBRUqsNMbL-HgaiwD5Blww9M3Upx8HRMFOAVhqh3AE4yHDyBX2BVBeE2APzjOWw7DYA1I+VjVwX7GEhwAeWmZAPiwtrPLbDgH2TmI5XqRUM+wyMJDQWm26oWWeCVOUBMjxDkNQ9D+XwQUMLguxnkqbBvNXNrPqV1wJpmr6eqW9bNpt77XCe0BXoIaoAL3nrAfA5fz-qfr6ah9fOCd-ft6NxXnZhfSN9u+pX6uyGRovTeqfFeztrb3xGoDF03EgR0QYjQGGAkj7AKoMYZ+FRwQACIPSYJLm1cEhsrr0FYtA3qcCKIINylgY+70EjoNgFgnBeDFLgklkwfShDNrYNFLg0MxJYBMGrPGM4HQ2bPgzMwVscA2hJ2jBINUXFSwghnJHKCBwVDKIWBqORtJDz-nABNQ+4AESgA5vhDUbCEbGPxMoPg0AnBYERLiIAA)

I think there's actually two issues here
 - [ ] The contextual type of the RHS of nullish operator is the type of the LHS
 - [ ] .then's type definition does not use overloads for different number of arguments

The first issue seems debatable, I can understand the current behavior but these alternates make sense as well
 1. The contextual type of R should be `unknown` or the same as the whole `L ?? R` expression
 2. The contextual type of  R should be `NonNullable<L>`
 
 > Let me know if this should be a separate issue or if there is interesting reading on the current behavior.
 
The next issue is caused because the return type of .then is `Promise<TResult1 | TResult2>` and TResult2 is not inferred from then's arguments when onrejected is not provided so it's inferred from the contextual type.
 
I think this issue can be fixed by changing the library to use overrides
```
then<TResult1>(onresolved: (t: T) => TResult1): Promise<TResult1>
then<TResult1, TResult2>(onresolved: (t: T) => TResult1, onrejected: (err: any) => TResult2): Promise<TResult1 | TResult2>
// more overrides for 0 or only onrejected args.
```


## Documentation Link

<!--
  Link to relevant documentation (e.g. MDN, W3C, ECMAScript Spec) to consult for this property.
  Note that lib.dom.d.ts intentionally does not include browser-specific extensions
   or early experimental features.
-->

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts#L1524