Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is it possible to dynamically determine the type by the name of the object's proxy key in TypeScript

I am writing a wrapper class that will contain functions for interacting with the user entity, such methods as checking that the user is a guest, functions for checking his permissions, etc. and one of the methods I want to make an accessor to its fields like name, email, id. And I had the idea that the accessor would return me data from the user himself by the name of the field in the entity. Here is the code I have and the comments to it that I want to change:

export interface UserModel {
  id: number
  name: string
  email: string
}

export class User {
  constructor(private _user: UserModel | null) {
  }

  // I can return the type I need through the generic, but I would like to be able to analyze the key that is in the UserModel model using the name parameter
  public get<T>(
    // This works great for me, autocomplete only lets me enter id,name,email
    name: keyof UserModel
  ): T {
    if (this._user === null) {
        throw new Error("User is empty.")
    }

    // And finally, instead of the generic T, I would like something like as UserModel[name]
    return this._user[name] as T
  }

  public isGuest(): boolean {
    return this._user === null;
  }
}

Is it possible to arrange this so that when I use the get method of an instance of the User class for example:

const user = new User({...})

// The typescript told me that the string type would be returned to me instead of using the generic type get<string>('email')
user.get('email') // return type string
user.get('id') // return type number

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You just need to capture the type of the key that is passed in using a generic type parameter. You can then use it to index into UserModel to get the actual type of the key passed in:

export class User {
  constructor(private _user: UserModel | null) {
  }

  
  public get<K extends keyof UserModel>(
    name: K
  ): UserModel[K] {
    if (this._user === null) {
        throw new Error("User is empty.")
    }
    return this._user[name]
  }

  public isGuest(): boolean {
    return this._user === null;
  }
}

Playground Link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading