Michael T.
Michael T.

Reputation: 197

Dynamic getters and settings for classes in TypeScript

I have a problem to retrieve data with dynamic getter on my class.

Here is the error I get:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'UserProps'. No index signature with a parameter of type 'string' was found on type 'UserProps'.ts(7053)

Here is the code

interface UserProps {
  name?: string;
  age?: number;
}

export class User {
  constructor(private data: UserProps) {}

  get(propName: string): number | string {
    return this.data[propName];
  }

  set(update: UserProps): void {
    Object.assign(this.data, update);
  }
}

Upvotes: 3

Views: 1376

Answers (1)

Aplet123
Aplet123

Reputation: 35512

The cleanest solution I could find is the following:

interface UserProps {
    name?: string;
    age?: number;
}

export class User {
    constructor(private data: UserProps) {}

    // Add generic magic here
    get<K extends keyof UserProps>(propName: K): UserProps[K] {
        return this.data[propName];
    }

    set(update: UserProps): void {
        Object.assign(this.data, update);
    }
}

Alternatively, you can add an arbitrary key indexing as well as update the type for your get statement.

interface UserProps {
    name?: string;
    age?: number;
    // this next line is important
    [key: string]: string | number | undefined;
}

export class User {
    constructor(private data: UserProps) {}

    // number|string changed to number|string|undefined
    get(propName: string): number | string | undefined {
        return this.data[propName];
    }

    set(update: UserProps): void {
        Object.assign(this.data, update);
    }
}

Upvotes: 4

Related Questions