'Classes & Keyof in Typescript

Beginning with TypeScript, I am trying to use keyof to define dynamic properties on a class:

type UserType = {
  id: number,
  name: string,
}

class Domain<T> {
  _data: T;
  [K in keyof T]: T[K]; // Does not build:
                        // (1) A computed property name must be of type 
                        //     'string', 'number', 'symbol', or 'any'
                        // (2) Cannot find name 'keyof'


  constructor(data: T) {
    this._data = data;
    Object.keys(data).forEach((key) => Object.defineProperty(this, key, { get: () => this._data[key] }));
  }
}

const joeData: UserType = {
  id: 1,
  name: 'Joe',
}

const joe = new Domain(joeData); // type: Domain<UserType>
console.log(joe.id);

I did write this code using the same (working) syntax as:

type Foo<T> = {
  [K in keyof T]: T[K];
}

Any hints on how to fix the issue?



Solution 1:[1]

I think that there is no way to dynamically specify class properties like this. It does not work in an interface either. I tried a variation of your class with implements Foo<T> and got this error:

A class can only implement an object type or intersection of object types with statically known members.

That leads me to believe that Typescript is specifically designed to avoid dynamically-specified class properties.

You can do this with a constructor that is not a class. You can use your Foo type as the return type of a function that constructs a plain object with getters. Or if all you need is a read-only version of an object you can use Object.freeze(data).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Grant Hutchins