简体   繁体   中英

How to get the type of a property by name using generics

I need a way to get the type of any property of a class or a type.

For example if I had the PersonClass and PersonType I want to get the nationalId type. I can do this:

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>

And it works ok nId3 is a number and nId4 is a string . But If I dont know how to do if I want to get any property. I try these:

// 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">

And I get:

在此输入图像描述

在此输入图像描述

You just want lookup types . If T is an object type and K is the type of one of its keys (or a union of such keys), then T[K] is the type of the value for that key (or the union of the value types for those keys):

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

If you feel the need to define GetProp , it is pretty straightforward without conditional types:

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

or if you must allow K that is not assignable to keyof T :

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

or if you really want to use infer and conditional types , you need a mapped type like Record :

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

But really the simple lookup type is the way to go, in my opinion.

Hope that helps. Good luck!

You need to use the mapped type syntax to do this with conditional types:

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

But I think you are really looking for a type query :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM