打字稿如何从类型中解包/删除承诺? [英] typescript how to unwrap/remove Promise from a type?

查看:27
本文介绍了打字稿如何从类型中解包/删除承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,它接受一个对象,其中每个道具都是一个承诺.它等待所有 promise 完成,然后返回一个具有相同 props 但现在已解析值的新对象.

i have a function that accepts an object where each prop is a promise. it waits for all the promise to finish then returns a new object with the same props but now resolved values.

resolved_props.company 应该是 string,而不是 Promise

// TODO: fix the types on this
function promise_props<T>(obj:T):Promise<T> {
  const keys = Object.keys(obj)
  const len = keys.length
  const awaitables = new Array<T>(len)
  for (var i = 0; i < len; i++) awaitables[i] = (obj as any)[keys[i]]

  return Promise.all(awaitables).then((results) => {
    const byName:any = {}
    for (var i = 0; i < len; i++) byName[keys[i]] = results[i]
    return byName
  })
}

推荐答案

您的类型不够准确,TypeScript 编译器无法确定它们不是承诺.

Your types are not accurate enough and the TypeScript compiler cannot figure it out that they are not promises at that point.

你需要的是这样的:

async function promise_props<T>(obj: {[key: string]: Promise<T>}): Promise<{[key: string]: T}> {
    const keys = Object.keys(obj);
    const awaitables = keys.map(key => obj[key]);

    const values = await Promise.all(awaitables);
    const result: {[key: string]: T} = {};

    keys.forEach((key, i) => {
        result[key] = values[i];
    });
    return result;
}

但只有当您的对象具有相同类型的承诺时它才会起作用,例如:

But it will only work if your object has promises of the same type, for example:

{
    company: Promise.resolve("company"),
    page: Promise.resolve("1")
};

我不确定在当前的 TypeScript 版本中是否可以让它与各种承诺类型一起工作,但正如 Tao 还建议的那样,您可以使用 TypeScript 2.8 中的新功能来让它工作:

I'm not sure if it is possible to get it working with various promise types in the current TypeScript version, but as Tao also suggested, you can use the new features in TypeScript 2.8 to get it working:

type UnPromisifiedObject<T> = {[k in keyof T]: UnPromisify<T[k]>}
type UnPromisify<T> = T extends Promise<infer U> ? U : T;

async function promise_props<T extends {[key: string]: Promise<any>}>(obj: T): Promise<UnPromisifiedObject<T>> {
    const keys = Object.keys(obj);
    const awaitables = keys.map(key => obj[key]);

    const values = await Promise.all(awaitables);
    const result = {} as any;

    keys.forEach((key, i) => {
        result[key] = values[i];
    });
    return result as UnPromisifiedObject<T>;
}

async function main() {
    const x = {
        company: Promise.resolve("company"),
        page: Promise.resolve(1)
    };
    const res = await promise_props(x);
    const company = res.company;  // company is a string here
    const page = res.page;        // page is a number here
}

如您所见,返回类型已正确推断.我认为该方法的实现可以改进.我找不到实例化返回类型的实例并使用 any 的方法,但是尽管编译器无法推断它,但它是类型安全的,因为我们解决了所有承诺.

As you can see, the return type is properly inferred. I think the implementation of the method can be improved. I couldn't find a way to instantiate an instance of the return type and use any, but although compiler cannot infer it, it's type safe as we resolve all promises.

这篇关于打字稿如何从类型中解包/删除承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆