Reputation: 2405
I'd like to know the best way to do this, say I have two objects
var objectA = {
propertyA: 1,
propertyB: 2
...
propertyM: 13
}
var objectB = {
propertyN: 14,
propertyO: 15
...
propertyZ: 26
}
If objectC is created by
var objectC = Object.assign(objectA, objectB);
How can I declare/describe objectC, so the compiler/IDE knows that it has the properties of both objectA and objectB?
I'd like to find a way without the need of defining interfaces for objectA and objectB. I don't want to write declaration and definition/evaluation for the same property twice. This redundancy is significant if I have too many properties on an object.
(Is there an operator that can extract the interface/type of an existing object?)
Is it possible?
Upvotes: 158
Views: 220398
Reputation: 3745
var apparel = [{
"ctaText": "Apparel BTN",
"formBlurb": "<ul><li>Apparel tracking and allergen management</li><li>Expiration tracking for waste reduction</li><li>Collaborative forecasting and versatile supply chain management</li></ul>",
"formImage": "",
"formHeading": "Fill out this form for apparel information.",
"marketoFormId": "2902",
"showModalSide": false,
"viewModalBackground": "dark",
"formImageTopPosition": "",
"successSubmissionCta": "Apparel Submit",
"successSubmissionMessage": "Thank you for choosing Apparel"
}];
var food = [{
"ctaText": "Food BTN",
"formBlurb": "<h4>Test blurb</h4><u>underline this text</u><ul><li>fashion</li><li>textiles</li><li>upholstery</li></ul>",
"formImage": "https://images.net/card-food-erp-for-quality-harvest-foods.jpg",
"formHeading": "Fill out this form for food information.",
"marketoFormId": "1086",
"showModalSide": true
}];
if (
Object.keys(apparel).length !=
Object.keys(food).length
) {
const initialDataFound = {...apparel, ...food };
console.log(this.initialDataFound);
}
Final result concates both apparel and food objects
Upvotes: 0
Reputation: 623
Use Typescript spread operator it transpile to Javascript Object.assign()
If you need deep tree object merging you could use changing function of best-global package
Upvotes: 7
Reputation: 371
Lodash has an "extend" function that combines objects and lets Typescirpt know that the new object has the type you'd expect.
const a = { one: 1, two: 2 };
const b = { three: 3, four: 4 };
const c = lodash.extend(a, b);
// c: { one: 1, two: 2, three: 3, four: 4 }
Upvotes: 4
Reputation: 1363
try this..
const person = { name: 'TRilok', gender: 'Male' };
const tools = { computer: 'Mac', editor: 'Atom' };
const attributes = { handsomeness: 'Extreme', hair: 'Brown', eyes: 'Blue' };
const summary = {...person, ...tools, ...attributes};
Upvotes: 15
Reputation: 4033
Seems like this should do the trick:
var objectA = {
propertyA: 1,
propertyB: 2,
.
. // more properties here
.
propertyM: 13
};
var objectB = {
propertyN: 14,
propertyO: 15,
.
. // more properties here
.
propertyZ: 26
};
var objectC = {...objectA, ...objectB}; // this is the answer
var a = objectC.propertyA;
var n = objectC.propertyN;
Based on this article: https://blog.mariusschulz.com/2016/12/23/typescript-2-1-object-rest-and-spread
In addition, the order of the variables in the decomposition matters. Consider the following:
var objectA = {
propertyA: 1,
propertyB: 2, // same property exists in objectB
propertyC: 3
};
var objectB = {
propertyX: 'a',
propertyB: 'b', // same property exists in objectA
propertyZ: 'c'
};
// objectB will override existing properties, with the same name,
// from the decomposition of objectA
var objectC = {...objectA, ...objectB};
// result: 'b'
console.log(objectC.propertyB);
// objectA will override existing properties, with the same name,
// from the decomposition of objectB
var objectD = {...objectB, ...objectA};
// result: '2'
console.log(objectD.propertyB);
Upvotes: 292
Reputation: 938
(Is there an operator that can extract the interface/type of an existing object? Is it possible?)
You should go for typeof.
type typeA = typeof objectA;
type typeB = typeof objectB;
To get them merged you can use intersection operation as basarat already pointed out.
type typeC = typeA & typeB
Upvotes: 19
Reputation: 276235
so the compiler/IDE knows that it has the properties of both objectA and objectB?
Use an intersection type + generics. E.g. from here
/**
* Quick and dirty shallow extend
*/
export function extend<A>(a: A): A;
export function extend<A, B>(a: A, b: B): A & B;
export function extend<A, B, C>(a: A, b: B, c: C): A & B & C;
export function extend<A, B, C, D>(a: A, b: B, c: C, d: D): A & B & C & D;
export function extend(...args: any[]): any {
const newObj = {};
for (const obj of args) {
for (const key in obj) {
//copy all the fields
newObj[key] = obj[key];
}
}
return newObj;
};
Both are mentioned here : https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html
Upvotes: 12