Search code examples
typescript

undefined stripped from type when accessing property


Code below is abridged and in screenshots. You can see a full working example here.

I have a small function which wraps Promise.all, returning the resolved values in an object instead of an array:

const allPromiseMap = async <T extends { [KEY in string]: unknown }>(map: {
  [KEY in keyof T]: Promise<T[KEY]>;
}): Promise<T> => {
  // ...
};

The idea is you pass in an object with Promise values and get back an object with the same keys but the resolved type from Promise as values.

Testing with some simple code, everything looks fine:

(async () => {
  const promises: {
    hello: Promise<string>;
    world?: Promise<number>;
  } = {
    hello: new Promise(() => { })
  }

  const responseMap = await allPromiseMap(promises);
  const worldResponse = responseMap.world;
})();

image showing the type of responseMap form the above code.  Demonstrating that it still has the optional tag on world

Even the optional tag on world is preserved!

However, when trying to store world in another variable, undefined is removed from the type:

image showing the type of worldResponse form the above code.  Demonstrating that it does not include undefined

For comparison, similar code without my function does not have this problem:

image of a simple object which is directly typed with the expected response type from the above code

I'm pretty sure this is some bit of meta type-data hanging on to my object behaving incorrectly so barring that this is expected behavior: Is there a better way I could type my function to avoid this behavior?


Solution

  • This is a fun one.

    It's not about underlined. It's possibly non existing properties, with your function, it knows they exist. You are telling it to add all the keys.

    Change world to become: world: Promise<number | undefined> and it will work.