Reputation: 99831
I'm experimenting with using a simple pattern for creating a type of 'value' object. To instantiate it, all properties should be specified in the constructor.
To avoid repeating the list of properties, I tried something like this:
interface Video {
id: number;
title: string;
}
class VideoCl implements Video {
constructor(properties: Video) {
for(const [k, v] of Object.entries(properties)) {
this[k] = v;
}
}
}
Unfortunately, Typescript will not allow this as it requires all the properties from the interface to exist on the class as well.
Is there a simple way to accomplish this that removes the need for repeating the properties?
Upvotes: 1
Views: 297
Reputation: 9242
You can accomplish this by using declaration merging with an interface of the same name. Keep in mind that by doing this you are effectively lying to TypeScript. Even if a property declared in the interface is missing, TypeScript won't care.
interface VideoCl extends Video { }
class VideoCl {
constructor(properties: Video) {
for(const [k, v] of Object.entries(properties)) {
this[k] = v;
}
}
}
Related to this, iterating over properties with Object.entries
, Object.keys
, or directly setting values with Object.assign
on a class is dangerous. TypeScript won't protect you from the following code.
const properties = { id: 1, title: '', func: null };
const cls = new VideoCl(properties);
cls.func(); // Runtime error
Upvotes: 1