I have a type like this:
type Cool = {
[key: string]: number
}
Now, let's say I have an object with that type:
let my: Cool = {
"asdf": 1,
"jkl": 2
}
When I run Object.entries(my)
, I get [["asdf", 1], ["jkl", 2]]
. This seems normal. However, I want to combine each key to form a string, like this:
let mystring = "";
Object.entries(my).forEach(entry => {
mystring = entry[1] + mystring;
});
I would expect that mystring
is equal to "jklasdf" and it is. However, I get a flow error on the mystring = ...
line. The error states:
Cannot cast
Object.entries(...)[0][1]
to string because mixed [1] is incompatible with string
Any thoughts on how to fix this? Thanks!
Object.entries
is typed as:
static entries(object: $NotNullOrVoid): Array<[string, mixed]>
And when you try to use a value of a mixed
type you must first figure out what the actual type is or you’ll end up with an error, so you can use Flow's type refinement :
Object.entries(my).forEach(entry => {
if (typeof entry[1] === 'number') {
mystring = entry[1] + mystring;
}
});
You could also just cast entry[1]
:
Object.entries(my).forEach(entry => {
mystring = Number(entry[1]) + mystring;
});
or add type to entry
like this entry: [string, any]
but note that using any
is completely unsafe, and should be avoided whenever possible.
DEMO
Your problem is with the algorithm, not the types.
First of all, if you want mystring
to equal "jklasdf"
, then you need to access the first index [0]
like this entry[0]
, because the first element in the array is the key of object, if that's what you're looking for.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs...
So your code -regardless of the types- should be:
let my = {
"asdf": 1,
"jkl": 2
}
let mystring = "";
Object.entries(my).forEach(entry => {
mystring = entry[0] + mystring; // access the 0th element
});
console.log(mystring);
// jklasdf
So, now your flow types have no problem at all. https://flow.org/try/#0C4TwDgpgBAwg9nANlAvFA3gKCjqBtAawhAC4oBnYAJwEsA7AcwF0y6BXAWwCMIrMBfTJkQRgUDqVgJkaLLigAiAIbkAJgDMFZAIwAabLgUArAoi1QATAKEixEyrUapFCgNyYA8lyMQAxsAA6CDpqGghyAAoJAEoA9TgqAFElXwALCODqEFQAPgwDHHtQpzRMqhA8AAYmKABqcRAHegZ3fmjXIA
But, if I would recommend a more readable code to achieve the same result:
let my = {
"asdf": 1,
"jkl": 2
}
let mystring = "";
for (const [key, value] of Object.entries(my)) {
mystring = [key, mystring].join('')
}
console.log(mystring);
// jklasdf
Or using Array.prototype.reduce
:
let my = {
"asdf": 1,
"jkl": 2
}
const mystring = Object.entries(my)
.reduce((result, [key, value]) => {
return result = [key, result].join('');
}, "");
console.log(mystring);
// jklasdf
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With