I'm trying to write a function which resolves all Promise values of an object:
const resolveObject = async (obj) => // pure JavaScript implementation
Object.fromEntries( // turn the array of tuples with key-value pairs back into an object
(await Promise.all(Object.values(obj))).map((el, i) => [ // Promise.all() the values, then create key-value pair tuple
Object.keys(obj)[i], // tuple contains the original object key
el, // tuple contains the resolved object value
]) // zips the split key/value arrays back into one object
);
The implementation works fine. Below is a usage example:
/* example input */
const exampleInput = { // <- { foo: Promise<string>, bar: Promise<{ test: number }>, baz: boolean }
foo: Promise.resolve("Hello World"),
bar: Promise.resolve({
test: 1234
}),
baz: false
}
const expectedOutput = resolveObject(exampleInput) // <- { foo: string, bar: { test: number }, baz: boolean }
/* expected output: strongly typed object with same keys and no Promise<> wrappers in signature */
This is where things start to fall apart. I'm expecting a strongly typed output with a similar signature as the input (just without the Promise wrappers), but instead, I get the following generic object output:
Promise<{ [k: string]: unknown; }>
So I started adding type annotations to the resolveObject
function:
const resolveObject = async <T>(
obj: { [K in keyof T]: Promise<T[K]> }
): Promise<{ [K in keyof T]: T[K] }> => { ... }
Now I receive a type conversion error: type '{ [k: string]: unknown; }' is not assignable to type '{ [K in keyof T]: T[K]; }'
I'm fairly new to TypeScript and don't really know what to do next (I know how to diagnose the error message, but I'm pretty sure that something with my type annotation/function signature is wrong). How can I achieve what I'm looking for?