函数解析对象的Promise值的正确类型:{[key:string}:Promise <T> => {[key:string]:T}

时间:2019-12-23 08:38:07

标签: typescript es6-promise

我有一个函数,该函数将遍历对象的字段,等待/解析其值,并返回一个具有相同字段但已实现值的新对象。

输入时遇到麻烦。

有任何线索吗?

我已经遍历了类似的事情:

export async function promiseAllObject<
  T,
  Obj = { [k: string]: PromiseLike<T> },
  NewObj = {
    [k in keyof Obj]: T;
  }
>(o: Obj): Promise<NewObj> {
  try {
    const resolvedEntries = await Promise.all(
      Object.entries(o).map(async ([k, v]) => {
        const newVal = await v;
        return [k, newVal];
      }),
    );
    return Object.fromEntries(resolvedEntries);
  } catch (e) {
    // If one of the promised fields fails, fail the whole object
    return e;
  }
}

// Example:
 const o = { foo: 12, bar: 42, toto: 'hello' };
const op = lodash.mapValues(async v => v);
/*
  just to get Promise as objects' values
{
    foo: Promise<string | number>;
    bar: Promise<string | number>;
    toto: Promise<string | number>;
}
*/

const oResolved = promiseAllObject(op);
/*
Promise<{
    foo: unknown;
    bar: unknown;
    toto: unknown;
}>
*/

但是TS认为值仍然是Promises,或者未知。

1 个答案:

答案 0 :(得分:1)

您可以如下声明promiseAllObjectResolvedPromise使用类型推断运算符infer):

// infer resolved type of Promise, e.g. Promise<string> ~> string
type ResolvedPromise<T> = T extends Promise<infer I> ? I : T

export async function promiseAllObject<O extends { [k: string]: PromiseLike<any> }>
    (o: O): Promise<{ [K in keyof O]: ResolvedPromise<O[K]> }> {
    // paste your implementation here
}
const oResolved = promiseAllObject({
    foo: Promise.resolve("foo"),
    bar: Promise.resolve(42),
    toto: Promise.resolve(true),
});
/*
oResolved: Promise<{
    foo: string;
    bar: number;
    toto: boolean;
}>
*/

Sample Code