【问题标题】:Mapping TypeScript types from Object => Object从 Object => Object 映射 TypeScript 类型
【发布时间】:2018-10-19 05:48:31
【问题描述】:

假设我有一个像这样的对象:

export const v = {
   a() : Promise<X>{

   },
   b() : Promise<Y>{

   },
   c() : Promise<Z>{

   }
}

我的问题是 - 有没有办法获得 v 的类型,但映射类型,使其看起来像这样:

export type V = {
  a: X, 
  b: Y,
  c: Z
}

基本上我将对象中的每个键映射到相应承诺的解析值。

基本上,我试图从静态声明的东西中派生出修改后的类型。

【问题讨论】:

    标签: typescript typescript-typings typescript2.0 tsc


    【解决方案1】:

    您可以使用条件类型和映射类型来做到这一点:

    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] };
    

    【讨论】:

      猜你喜欢
      • 2022-07-26
      • 2020-11-17
      • 2016-07-08
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 2022-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多