Flow type and merging json objects - javascript

Assume code of the following kind (e.g. using lodash or explicitly like here):
function extend(base, overwrite) {
for (var key in overwrite)
base[key] = overwrite[key];
return base;
}
var first = extend({
a: 1
}, {
b: 2
});
var second = extend({
c: 3
}, {
d: 4
});
console.log(first.a + first.b + second.c + second.d);
How can I explain to Flowtype that this is actually fine?

Try putting this just above function declaration:
declare function extend<A, B>(a: A, b: B): A & B

Related

Destructure and retrieve the fully structured variable in one expression [duplicate]

This question already has answers here:
Destructure object parameter, but also have reference to the parameter as an object? [duplicate]
(2 answers)
Closed 3 years ago.
Is it possible to both destructure a variable and have access to the structured variable in the same call?
For example, what could I replace ??? below to get the desired output (and how else might I have to edit my code)
const foo = ({ a, b }) => {
console.log(a) // 1
console.log(b) // 2
console.log(???) // { a: 1, b: 2 }
}
const x = { a: 1, b: 2 }
foo(x)
My goal is knowledge and succinct code - I want to avoid const { a, b } = params as the first line of foo() in the case where I might need to pass the entire params object on.
If the first argument is an object whose reference you want, it's not possible - once you destructure an argument, there's no longer any way to reference to the full argument, only some of its properties.
It would be possible if the object and parts you wanted was part of a larger object, though, because then you can reference the property name alone (to get the object into a variable), and then reference it again to destructure, eg:
const foo = ({ obj: { a, b }, obj }) => {
console.log(a) // 1
console.log(b) // 2
console.log(obj) // { a: 1, b: 2 }
}
const obj = { a: 1, b: 2 }
foo({ obj })
Your original code could work to an extent if the object had a property that referenced itself, but that's pretty weird:
const foo = ({ a, b, obj }) => {
console.log(a) // 1
console.log(b) // 2
console.log(obj) // { a: 1, b: 2 }
}
const x = { a: 1, b: 2 }
x.obj = x;
foo(x)

JSON Definitions Using Internally Defined Variables [duplicate]

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 5 years ago.
I am trying to create a JSON object to store some parameters for a program. Some of the parameters need to be calculated from others as they are being defined. I would like to do this within the object definition but maybe this is not possible
var params = {
a: 50,
b: 70,
c: this.a+this.b
}
Result
What happens
>params.c
NaN
What I wished happened
>params.c
120
Edit
After doing some further reading, I think I am using Object Literal Notation instead of JSON.
You can use this approach:
To avoid re-calculation, use the function Object.assign.
The get syntax binds an object property to a function that will be called when that property is looked up.
var params = {
a: 50,
b: 70,
get c() {
console.log('Called!');
return this.a + this.b;
}
};
console.log(params.c); // Prints 120 then Called!
console.log(params.c); // Prints 120 then Called!
var params = Object.assign({}, {
a: 50,
b: 70,
get c() {
console.log('Called from function Object.assign!');
return this.a + this.b;
}
});
params.a = 1000; // To illustrate.
console.log(params.c); // Prints 120
console.log(params.c); // Prints 120
.as-console-wrapper {
max-height: 100% !important
}
Resources
Object initializer
getter
Personally, I would create constants (since magic numbers are the devil), but this is an overly-simplistic example:
const FIFTY = 50;
const SEVENTY = 70;
var params = {
a: FIFTY,
b: SEVENTY,
c: FIFTY + SEVENTY
};
What I would recommend doing is starting with an object that does not contain c, and taking the calculation outside of the object. Once the calculation has occurred, simply add the sum back to the object as a new key/value pair:
var params = {
a: 50,
b: 70,
}
var sum = 0;
for (var el in params) {
if (params.hasOwnProperty(el)) {
sum += params[el];
}
}
params['c'] = sum;
console.log(params);

looping through parameters in angular 4 (typescript) constructor?

In an angular 4 model, I have some typescript code that looks like this:
export class Thing {
public a: number;
public b: number;
public c: number;
constructor(a, b, c){
this.a = a || 0;
this.b = b || 0;
this.c = c || 0;
}
}
This seems an obvious place to use a loop, or something simpler than declaring variables a, b, and c and then following up with assigning a, b, and c, via the constructor.
Not sure how to get that done though.
You can also do this. Declare your variables via access modifiers in the constructor. This will automatically create your fields with that access modifiers and assign to them the values which you pass. Also you can assign default values to the parameters, if the value passed will be undefined.
export class Thing {
constructor(public a: number = 0,
public b: number = 0,
public c: number = 0) {
}
}
const thing = new Thing(1, 2);
// thing.a = 1
// thing.b = 2
// thing.c = 0 - default value
One Note also. Angular 5 is released. You can use it.

Enum using empty objects

We can create "Enums" in Javascript as follows:
var MyEnum = {
A: 0,
B: 1,
}
Can I use empty objects instead of numbers as follows?
var MyEnum = {
A: {},
B: {},
}
What's the difference and which should be used? There isn't any specific use case.
I changed my answer after you edited because just noticed what you are trying.
Yes you can use objects as enum value without any problem. When you define {} in an object, it creates and empty object with unique reference.
{} != {} won't be equal because two different objects with same doesn't mean they are same object. Two red balls you have, these balls are the same ball? No.
But instance.type == MyEnum.ObjectEnum1 will always be true.
Because both instance and the MyEnum object shares the same reference to the object.
var MyEnum = {
A: 1,
B: 2,
C: 3,
ObjectEnum1: {},
ObjectEnum2: {}
}
var obj1 = {
type: MyEnum.B
}
var obj2 = {
type: MyEnum.C
}
var obj3 = {
type: MyEnum.ObjectEnum1
}
console.log(obj1.type == MyEnum.B); //Should be true
console.log(obj2.type == MyEnum.A); //Should be false
console.log(obj2.type == MyEnum.C); //Should be true
console.log(obj3.type == MyEnum.ObjectEnum1); //Should be true
console.log(obj3.type == MyEnum.ObjectEnum2); //Should be false

Shorthand for creating object with same field [duplicate]

This question already has answers here:
One-liner to take some properties from object in ES 6
(12 answers)
Closed 5 years ago.
const json = {
a: 1,
b: 2,
c: "HI"
}
Is there a way to just pass in {a : 1} to function?
var someReturn = aOnly({a : json.a});
I am not sure if destructuring/constructuring of ES6 solves this problem. I can't seem to find the right syntax after reading several ES6 destructuring example.
EDIT
Nothing is wrong with the code I am just asking if there is a syntax to just extract "a" only from JSON without redundantly doing
{a : json.a }
the implementation of aOnly function is not the focus here
You can use ES6 object destructuring on object passed as parameter to pick specific property.
const json = {
a: 1,
b: 2,
c: "HI"
}
function aOnly({a}) {
return a;
}
var someReturn = aOnly(json);
console.log(someReturn)
Thank you I have figured out the right syntax. The initial mistake I was doing was trying to construct directly using { json.a }, hoping that this will automatically turn into { a : json.a} but the right way is do destruct first and construct later.
var json = {
a : "ASDF",
b : 123,
c : "Test"
};
const {a, b, c} = json; // destructing
var aObject = aOnly({a}); // constructing
var bObject = bOnly({b});
var cObject = cOnly({c});
console.log (aObject);
console.log (bObject);
console.log (cObject);
function aOnly(a) { return a; }
function bOnly(b) { return b; }
function cOnly(c) { return c; }

Categories

Resources