Flow 允许连接 object.entries 和字符串

Flow allow concatenation with object.entries and string

我有这样的类型:

type Cool = {
    [key: string]: number
}

现在,假设我有一个该类型的对象:

let my: Cool = {
    "asdf": 1,
    "jkl": 2
}

当我 运行 Object.entries(my) 时,我得到 [["asdf", 1], ["jkl", 2]]。这似乎很正常。但是,我想将每个键组合成一个字符串,如下所示:

let mystring = "";
Object.entries(my).forEach(entry => {
    mystring = entry[1] + mystring;
});

我希望 mystring 等于 "jklasdf",确实如此。但是,我在 mystring = ... 行收到流程错误。错误状态:

Cannot cast Object.entries(...)[0][1] to string because mixed [1] is incompatible with string

关于如何解决这个问题有什么想法吗?谢谢!

Object.entries 输入为:

static entries(object: $NotNullOrVoid): Array<[string, mixed]>

并且当您尝试使用 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;
  }
});

你也可以只施放 entry[1]:

Object.entries(my).forEach(entry => {
  mystring = Number(entry[1]) + mystring;
});

或像这样 entry: [string, any] 添加类型到 entry 但请注意 使用 any 是完全不安全的,并且应尽可能避免。

DEMO

你的问题出在算法上,而不是类型上。

首先,如果你想让mystring等于"jklasdf",那么你需要像这样entry[0]访问第一个索引[0],因为第一个元素在数组中是对象的键,如果这就是您要查找的内容。

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...

所以你的代码——不管类型——应该是:

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

所以,现在你的流类型完全没有问题了。 https://flow.org/try/#0C4TwDgpgBAwg9nANlAvFA3gKCjqBtAawhAC4oBnYAJwEsA7AcwF0y6BXAWwCMIrMBfTJkQRgUDqVgJkaLLigAiAIbkAJgDMFZAIwAabLgUArAoi1QATAKEixEyrUapFCgNyYA8lyMQAxsAA6CDpqGghyAAoJAEoA9TgqAFElXwALCODqEFQAPgwDHHtQpzRMqhA8AAYmKABqcRAHegZ3fmjXIA

但是,如果我推荐一个更具可读性的代码来实现相同的结果:

let my = {
    "asdf": 1,
    "jkl": 2
}

let mystring = "";
   
for (const [key, value] of Object.entries(my)) {
    mystring = [key, mystring].join('')
}

console.log(mystring);
// jklasdf

或使用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