If you want a generic way of filling any object with data from an array of values, you can do the following (as long as you declare the properties in the class in the same order as the data comes in the array):
class User {
firstName = '';
lastName = '';
userName = '';
email = '';
}
const data = [
["Adam", "Richardson", "AdMan", "[email protected]"],
["Ahmad", "Ali", "MarketMan", "[email protected]"],
["Feng", "Trunk", "SuperMan", "[email protected]"],
["Chris", "Garcia", "SmartMan", "[email protected]"]
];
function fromDataArray<T>(klass: new () => T, data: any[]) {
const obj = new klass();
Object.keys(obj).forEach((k, i) => obj[k] = data[i]);
return obj;
}
const users = data.map(d => fromDataArray(User, d));
One of the problems you have with making a generic method that works on nested objects is that all of the types are lost once the TypeScript is transpiled to JavaScript. The only way to eliminate that problem is to have initial objects in your classes that instantiate the properties that are supposed to be objects with an instance of that type to use.
Here is an example that would work with a nested object of such data arrays to show you that it can be done:
function fromDataArray<T>(klass: new () => T, data: any[]) {
const obj = new klass();
Object.keys(obj).forEach((k, i) => {
if (Array.isArray(obj[k])) {
if (obj[k].length && typeof obj[k][0] === "object") {
obj[k] = data[i].map(d => fromDataArray(obj[k][0].constructor, d));
}
else {
obj[k] = data[i];
}
}
else if (typeof obj[k] === "object") {
obj[k] = fromDataArray(obj[k].constructor, data[i])
}
else {
obj[k] = data[i];
}
});
return obj;
}
class SubClass3 {
email = '';
}
class SubClass2 {
userName = '';
stuffz = [new SubClass3()];
}
class SubClass1 {
lastName = '';
subClass2 = new SubClass2();
}
class Class1 {
firstName = '';
subClass1 = new SubClass1();
}
const data = [
["Adam", ["Richardson", ["AdMan", [ [ "[email protected]"] ]]]],
["Ahmad", ["Ali", ["MarketMan", [ [ "[email protected]"] ]]]],
["Feng", ["Trunk", ["SuperMan", [ [ "[email protected]"] ]]]],
["Chris", ["Garcia", ["SmartMan", [ [ "[email protected]"] ]]]]
];
const crazyData = data.map(d => fromDataArray(Class1, d));
This will give an array of objects that look like the following.
As a note, this is the JSON representation, but they are objects of the appropriate type.
{
"firstName": "Adam",
"subClass1": {
"lastName": "Richardson",
"subClass2": {
"userName": "AdMan",
"stuffz": [
{
"email": "[email protected]"
}
]
}
}
}