Typescript object mapping for keys in child object

Viewed 48

I have the following setup:

class Table{
    public values: DefaultTableValues;
}

class User extends Table{
    public values!: UserValues;
    constructor() {
        super();
        this.values={username:'test', avatar:''}
    }
}

interface UserValues extends DefaultTableValues{
    avatar:string;
    username:string;
}

I am trying to add a getColumns method to Table that would return (for a User instance): {username:'username', avatar:'avatar'}

This works:

public getColumns() {
        const copy = this.values;
        let arr = Object.keys(copy) as Array<keyof typeof copy>
        return arr.reduce((ac, a) => ({...ac, [a]: a}), {});
}

But Typescript/my IDE are not mapping it correctly. If I try something like userInstance.getColumns().avatar I get property avatar does not exist on type {}.

Is there a way to assert that this.getColumns() has the same keys as this.values?

1 Answers

I would define the values in Table using generics:

class Table<T = DefaultTableValues>{
    public values!: T;

    public getColumns() {
        return this.values
    }
}

Then in User class

class User extends Table<UserValues> {
    public values!: UserValues;
    constructor() {
        super();
        this.values = {username:'test', avatar:''}
    }
}

So, provided that u is a user instance, u.getColumns() would return UserValues

Related