代码之家  ›  专栏  ›  技术社区  ›  Emilio Platzer

如何使用泛型按名称获取属性的类型

  •  1
  • Emilio Platzer  · 技术社区  · 6 年前

    我需要一种方法来获取类或类型的任何属性的类型。

    例如,如果我有 PersonClass PersonType 我想得到那份工作 nationalId 类型我可以这样做:

    class PersonClass{
        name: string
        nationalId: number
    }
    
    type PersonalType={
        name: string
        nationalId: string
    }
    
    type GetNationalIdType<T> = T extends {nationalId: infer U} ? U : never;
    var nId3: GetNationalIdType<PersonClass>
    var nId4: GetNationalIdType<PersonalType>
    

    它工作正常 nId3 是一个 number nId4 是一个 string . 但如果我不知道如何做,如果我想得到任何财产。我试试这些:

    // type GetProp<T, K> = T extends {[key: K]: infer U} ? U : never;
    type GetProp<T, K extends string> = T extends {[key: K]: infer U} ? U : never;
    
    var nId1: GetProp<PersonClass, "nationalId">
    var nId2: GetProp<PersonalType, "nationalId">
    

    我得到:

    enter image description here

    enter image description here

    2 回复  |  直到 6 年前
        1
  •  2
  •   jcalz    6 年前

    你只是想 lookup types . 如果 T K 是其一个键(或这些键的并集)的类型,则 T[K] 是该键的值类型(或这些键的值类型的并集):

    var nId1: PersonClass["nationalId"]; 
    var nId2: PersonalType["nationalId"];
    

    如果你觉得有必要定义 GetProp ,它非常简单,没有条件类型:

    type GetProp<T, K extends keyof T> = T[K];
    

    或者如果你必须允许的话 K 这是不可转让的 keyof T :

    type GetProp<T, K extends keyof any> = K extends keyof T ? T[K] : never;
    

    或者如果你真的想用 infer conditional types Record :

    type GetProp<T, K extends keyof any> = T extends Record<K, infer V> ? V : never;
    

    但在我看来,简单的查找类型才是真正的出路。

        2
  •  1
  •   Titian Cernicova-Dragomir    6 年前

    您需要使用映射类型语法来处理条件类型:

    type GetProp<T, K extends string> = T extends {[key in K]: infer U} ? U : never;
    

    但我认为您实际上在寻找类型查询:

    var nId1: PersonClass["nationalId"]
    var nId2: PersonalType["nationalId"]