如何在Typescript中为已解析的promise创建映射类型

时间:2017-12-31 04:17:39

标签: typescript

我希望能够拥有已解决的promise值的映射类型。

此映射类型会传播所有密钥:

type PromisifiedKeys<T> = { [K in keyof T]: Promise<T[K]> }

我想要一个不同义/解决它们的映射类型:

type PromisifiedKeys<T> = { [K in keyof T]: UnPromise<T[K]> }

我不知道该怎么做。

2 个答案:

答案 0 :(得分:1)

你真的想要mapped conditional types,它目前不存在于TypeScript中。

有解决方法。如果您愿意Promise<T> declare global { interface Promise<T> { "**unPromise**": T } } export type UnPromise<T extends Promise<any>> = T['**unPromise**'] export type UnPromisifiedKeys<T extends { [k: string]: Promise<any> }> = {[K in keyof T]: UnPromise<T[K]> } 使用幻像属性,则可以执行以下操作:

type Promised = {
  foo: Promise<string>,
  bar: Promise<number>
}
type UnPromised = UnPromisifiedKeys<Promised>; 
// {foo: string, bar: number}

你得到:

PromisifiedKeys<T>

这或多或少都是你要求的,但它很骇客。

或者,您可以使用pollute the global declaration来获取一个类型为T的对象并返回declare function unPromisifyKeys<T>(k: PromisifiedKeys<T>): T; 的函数:

UnpromisifyKeys<T>

这表示您想要对类型执行的操作。如果您想要传递给此函数的具体内容,它可能对您有用。 (也就是说,如果您只是寻找UnpromisifyKeys<T>作为表示函数输出的方法,那么此解决方案将按原样运行)。如果你确实需要在类型级别找出T而没有具体的const unpromised = true as false || unPromisifyKeys(null! as Promised); type Unpromised = typeof unpromised; // {foo: string, bar: number} 值,那么你可以跳过箍来强制编译器推断出正确的类型,而不会在运行时引起太多繁忙的工作:

Promise<T>

这个有效但很难看。它在第一个解决方法中唯一的用途是LuisAppId的全局定义不变。

也许其中一个解决方法对你来说足够好了吗?希望有所帮助;祝你好运!

答案 1 :(得分:1)

从Typescript 2.8开始,有条件类型。来自handbook

type Unpacked<T> =
    T extends (infer U)[] ? U :
    T extends (...args: any[]) => infer U ? U :
    T extends Promise<infer U> ? U :
    T;

用法示例:

const p: Promise<string> = getData();
type ReturnDataType = Unpacked<p>;

我能够这样实现:

interface AsyncSupplementalData {
    couponCodeData: Promise<string>;
}
interface ApplicationState {
    [K in keyof AsyncSupplementalData]: Unpacked< AsyncSupplementalData[K] >
}