How do I declare a Generic Promise in Typescript, so that when the Generic type is "<void>", one of its methods won't take a parameter?

Taytay picture Taytay · Jul 3, 2014 · Viewed 29.4k times · Source

In Typescript, I want to be able to define a Promise's type in such a way so that I can do this:

//This works today:
new Promise<number>((resolve)=>{
   //Cool
   resolve(5);
   //Error, because I didn't pass a number:
   resolve();
}

//This is what I want to do also:
new Promise<void>((resolve)=>{
   //Error, because I passed a value:
   resolve(5);
   //Cool, because I declared the promise to be of type void, so resolve doesn't take a value:
   resolve();
}

The promise definition files I've seen all declare that the "resolve" method of a promise must take a value. Here is a recent example from the wonderful DefinitelyTyped project:

declare class Promise<R> implements Thenable<R> {
    constructor(callback: (resolve : (result: R) => void, reject: (error: any) => void) => void); 
///...
}

```

That basically says, "The resolve callback must be passed a value of type R." That's fine for a promise like new Promise<number>. Typescript will verify we're calling resolve with a value of type number.

However, what if I want a promise that doesn't have a value, so I want to be able to call resolve() without passing a value? I can declare my promise like this: new Promise<void> But then I'm still forced to call resolve and pass in a value of some sort. I can call resolve(undefined), but that reads a bit strangely.

There appears to be no way to properly capture this concept in Typescript: "If this generic has a type 'void', then don't expect a parameter for this function."

The closest I can do is mark the result as optional in the resolve method, but that would mean that the result is always optional, even for typed versions of Promises.

Answer

Anders picture Anders · Jul 29, 2014

This do work!
The promise definitions were updated to support such a use case.

Runnable example is too long to be posted. But just copy/paste newest definitions and your Promise code into a an editor and you will see that your example now works.