Reputation: 468
I have a class I can't change, simplified version shown. I got an array of variations on the class. I need to add the rest of the class to each member of the array before I can use them.
class ValueType {
name: string;
size: number = 5;
constructor(source?: {
name?: string;
size?: number;
}) {
if (source) {
Object.assign(this, source);
}
}
};
So this can be done by adding the class to each member of the array individually, either of these two ways, but that, with a big array, is 'messy code' IMHO.
let test1 = [new ValueType({
name: 'john',
})];
console.log('tv1 is:', test1[0].size); // 5
// OR
let test2 = [{
name: 'paul',
...new ValueType()
}];
console.log('tv2 is:', test2[0].size); // 5
Here's my attempt at an declarative way, but it doesn't work. It doesn't allow you get the default value of the un-updated items.
let test3: Partial<ValueType>[] = [{
name: 'tom',
}];
console.log('tv3 is:', test3[0].size); // undefined
Finally, here's an imperative approach that achieves what I want, but I can't help but think that TypeScript has a better way of doing this with types, Utility Types, ANDs, ORs, etc!
let test4: ValueType[] = [{
name: 'tom',
}].map(value => Object.assign(value, new ValueType()));
console.log('tv4 is:', test4[0].size);
Upvotes: 1
Views: 90
Reputation: 144
Typescript doesnt adds codes to JS Objects at runtime. So to achieve what do you want, you need to declare an factory method (check for Factory Pattern).
So, in your exemple, the factory will receive data as params, and return the instance desired. You can declare a factory function or an static factory method inside your class.
function factoryValueType(data: Partial<ValueType>): ValueType {
return new ValueType(data);
}
class ValueType {
name: string;
size: number = 5;
constructor(source?: {
name?: string;
size?: number;
}) {
if (source) {
Object.assign(this, source);
}
}
static fabricate(data): ValueType {
return new ValueType(data);
}
}
valueTypeList: ValueType[] = [
ValueType.fabricate({name: 'John'}), // use factory as static method
factoryValueType({name: 'Doe'}), // use factory as function
]
You can utilize this to transform json objects
valueTypeList: ValueType[] = jsonList.map(obj => factoryValueType(obj));
Using factory pattern is cleaner and safier, you can debug and create test for your factories. Just remeber that there is no unique solution, this examples abouve is just one of them.
Upvotes: 1