您可以使用条件类型和映射类型来做到这一点:
class X{}
class Y{}
class Z{}
export const v = {
a() : Promise<X>{
return null as any;
},
b() : Promise<Y>{
return null as any;
},
c() : Promise<Z>{
return null as any;
},
}
type ExtractAllPromisses<T> =
{
// Take all keys of T ([P in keyof T])
// and if the property P of T is a promise returning function (T[P] extends ()=> Promise<infer U>)
// then the new type of P will be the return type of the promise (saved in U)
// Otherwise the new type of P is never
[P in keyof T]: T[P] extends ()=> Promise<infer U> ? U : never
};
export type V = ExtractAllPromisses<typeof v> // same as type V = { a: X; b: Y; c: Z; }
根据您的需要,您可以在条件类型中做一些变化,上面的示例专门适用于仅具有不带参数并返回 Promise 的函数的类型。
如果你想用任意数量的参数匹配一个函数,你可以使用:
type ExtractAllPromisses<T> = { [P in keyof T]: T[P] extends (...args: any[])=> Promise<infer U> ? U : never };
如果您的类型还具有不承诺返回函数的属性并且您希望保留这些属性(即v 也有一个字段foo:number),您可以使用:
type ExtractAllPromisses<T> = { [P in keyof T]: T[P] extends (...args: any[])=> Promise<infer U> ? U : T[P] };
如果您想排除不是 Promise 重新调整功能的属性。您可以过滤键:
type PromiseFunctionFields<T> = { [P in keyof T] : T[P] extends (...args: any[])=> Promise<any> ? P : never}[keyof T];
type ExtractAllPromisses<T> = { [P in PromiseFunctionFields<T>]: T[P] extends (...args: any[])=> Promise<infer U> ? U : T[P] };