Typescript: `resolve()` of a promise accepts `undefined` when explicit generic type is specified

Created on 12 Feb 2020  路  6Comments  路  Source: microsoft/TypeScript

I am confused. It well can be the result of ECMAScript spec or something, but all this doesn't make sense to me.
TypeScript Version: 3.7.x-dev.201xxxxx
Search Terms: promise undefined and I looked through all of the 5 pages + looked through FAQ
Code:

type TypeA = {
  value: number;
}
const test = (): Promise<TypeA> => {
  return new Promise<TypeA>(resolve => {
    resolve(undefined); // Result of test() is Promise of TypeA. I return a promise that is resolved with  undefined and it's ok for some reason.
  });
};

const test2 = (): Promise<TypeA> => {
    return Promise.resolve(undefined);
};
test().then(typeAInstance => {
  // At this point here `typeAInstance` is of type TypeA and not! of `TypeA | undefined`
  console.log(typeAInstance.value.toFixed())
});

Expected behavior:
Both Functions should prevent me from doing writing stupid code at compile time.

Actual behavior:
Only second one does prevent me. First one allows runtime error to happened in the end.

Playground Link: http://www.typescriptlang.org/play/?ts=3.8.0-dev.20200211&ssl=1&ssc=1&pln=14&pc=4#code/C4TwDgpgBAKuEEEoF4oG8BQUoDcCGANgK4QBcUAdkQLYBGEATgNwYC+GAxgPYUDOwUYBH4ooACgCU5AAoMu1AJa8IAHjiQEAPhTbM2BhGBEGFShADuUWfKWr1iTWIO8uBHNGS6s2KM9fuxIgoAEwgAMwUKCGCJFmxWWLYWbj4BIX4AJlFJGTlFZTV4LR10b31DY1NrfIgAOj83CECQ8MjoxNYWdOBJWuAACwgKMVANAElUvAoODy9sFJcCOoIuAHMRoon+KZna-GI64C4AMQUAD2jJCTZYoA

Related Issues:

I don't understand where this undefined as one of the potential argument types is coming from:
Screen Shot 2020-02-12 at 7 38 11 PM

My lib.es5.d.ts contains this:

declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;

My lib.es2015.promise.d.ts contains this:

new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
Fix Available Needs Investigation Rescheduled

Most helpful comment

This came up recently in our team chat and it was surprising to several of us. According to @rbuckton:

Because we (at the time) had no way to do new Promise<void>(resolve => resolve()). Now we do (because void parameters are optional), so we can probably tighten up that definition.

So I鈥檓 going to leave this open so we can revisit it.

All 6 comments

duplicate of #22040


I don't understand where this undefined as one of the potential argument types is coming from

It's an optional argument, and therefore accepts undefined.

@jcalz yeah, seems to be a duplicate. This is really a shame. I raised it because this caused an issue in production for me just now and I was really surprised TS can't handle such a simple case.
If resolve by default allows an optional argument, then all the .then callbacks should be also expected to be called with undefined regardless of the generic type defined.

This came up recently in our team chat and it was surprising to several of us. According to @rbuckton:

Because we (at the time) had no way to do new Promise<void>(resolve => resolve()). Now we do (because void parameters are optional), so we can probably tighten up that definition.

So I鈥檓 going to leave this open so we can revisit it.

crosslinking to #27522
will this run afoul of #29131 ?

Hi, I'm running into a similar problem with type specificity for a generic callback type in our code on the mongodb node driver. The current callback definition looks something like:

type Callback<T = any> = (error?: Error, result?: T) => void;

Our desire is to explicitly disallow undefined for the result type, and I was hoping this would do the trick:

type Callback<T = any> = (error: Error | undefined | void, result: T | void) => void;

Alas it seems undefined equates to void in this case, so the elision of the void parameter isn't necessarily specific to the Promise case.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tenry92 picture tenry92  路  146Comments

RyanCavanaugh picture RyanCavanaugh  路  205Comments

kimamula picture kimamula  路  147Comments

xealot picture xealot  路  150Comments

jonathandturner picture jonathandturner  路  147Comments