Repository: TypeScript
Issue: Deeper inference of Promise types.
Labels: Suggestion,In Discussion

# Suggestion

## 🔍 Search Terms

promise required infer label:Suggestion 

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

In TypeScript 4.1 the first argument of a promise's `resolve` function was made to be required rather than optional (see [this blogpost](https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#resolves-parameters-are-no-longer-optional-in-promises)). This is useful because it often catches legitimate bugs. The downside is that you always have to provide a type argument. It would be nice if TypeScript were better at inferring the types of Promises so that you don't always have to provide a type.
So for instance

```ts
new Promise(r => r(3));
```

Would automatically result in the type `Promise<number>`.

## 📃 Motivating Example

In TypeScript having to provide a type is not such a big deal. You can usually get away with something like:

```ts
await new Promise<number>(r => r(3));
```

But in Javascript with JSDoc, this same piece of code becomes:

```js
/** @type {Promise<number>} */
const promise = new Promise(r => r(3);
await promise;
```
which is generally a lot less clean and less readable than the TypeScript equivalent.

## 💻 Use Cases

I frequently find myself running across code like the following:

```js
/** @type {(() => void)[]} */
const cbs = [];

async function test() {
    // Do something

    // wait until `cbs` have fired
    await new Promise(r => r());

    // Do something else
}
```

All I want to do here is wait in the middle of an async function until a certain event has happened and then move on. I won't even be using the return value of the promise most of the time.

But because the first argument is required, TypeScript will now complain that I'm calling `r()` without any arguments. (here's [a playground example](https://www.typescriptlang.org/play?strictNullChecks=true&noUncheckedIndexedAccess=true&noUnusedLocals=true&noUnusedParameters=true&useUnknownInCatchVariables=true&exactOptionalPropertyTypes=true&noFallthroughCasesInSwitch=true&noImplicitOverride=true&noPropertyAccessFromIndexSignature=true&filetype=js#code/PQKhAIAEBcE8AcCm4DeAKNBKcBeAfOAG4D2AlgCaYDaAugL7gjABQAxsQHYDO04rARl1zhaAbmbMAhl1gdW4AGYBXOdFKdw0RDyypm4A+GDBwAEWLguxALaJoAC1IcA5hMNGTAd0mleKtQA24AAGAlzB4PaShMgKpABOiOT6hpLevuAciJ7gAArxNqRciGjxuATxWJjiKQbGZhZWtg5OzuCIAcXMdEA))

If the return type of the promise would be inferred, there' wouldn't be the need to create an extra variable and annotate the promise with the `Promise<void>` type.