Home > database >  is there a way to handle property assignment dynamically with a class expression?
is there a way to handle property assignment dynamically with a class expression?

Time:03-25

if I have the following:

const c = class {
  xyz = 123;
};

then I can do:

new c().xyz // --> 123;

Is there a way to supply an object to automatically set properties? In other words, I would like to do something like:

const props = { foo: 'baz!', bar: 555 };
const c = class {
  ...props... // magically convert props to properties -- but how?
};

and be able to do:

new c().foo; // --> 'baz!'
new c().bar; // --> 555

Is this possible?

CodePudding user response:

There's not a good way that's perfectly type safe. But you can use Object.assign(this, props) in the constructor to bring all those properties into the instance, but Typescript doesn't really know what that function does or how it affects the type.

What makes this not so good as that you will also need to cast the result manually.

You can make a generic function to do this for you:

function makeClass<T>(props: T) {
  return class {
    constructor() {
      Object.assign(this, props);
    }
  } as { new (): T }
}

const C = makeClass({ foo: 'baz!', bar: 555 });
const c = new C();
console.log(c.bar); // fine
console.log(c.foo); // fine
console.log(c.nope); // error

Note the as { new (): T } which means that this is a value that you can invoke with new to return an interface that is you're props T.

This solution may get more complicated if your class also has other properties, but it's a start.

Playground

  • Related