流程允许Object.entries和字符串进行连接拼接。

7
我有这样一个类型:
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 = ...这一行上,我遇到了流程错误。错误提示如下:

无法将Object.entries(...)[0][1]转换为字符串,因为混合[1]与字符串不兼容

你有什么想法可以解决这个问题吗?谢谢!


1
奇怪的是,当我在 https://flow.org/try/ 中输入您的代码时,它显示没有错误。 - BoltKey
根据Flow的核心类型,Object.entries的结果是一个Array<[string, mixed]>,因此访问entry[0]应该产生一个字符串(参考)。也许你正在尝试访问entry[1](它的类型可能是mixed)? - user11307804
谢谢@user11307804!事实上我正在访问entry[1]! - Ryan Z
@RyanZ,如果你还在遇到这个问题,请参考https://github.com/facebook/flow/issues/2221。 - user11307804
2个回答

7

Object.entries的类型为:

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

当您尝试使用mixed类型的值时,您必须首先确定实际类型,否则会出现错误,因此您可以使用Flow的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添加类型:entry: [string, any],但请注意使用any是完全不安全的,应尽可能避免使用。

演示


为什么 Object.entries 没有像 Object.fromEntries 一样使用泛型进行类型标注?如果一个类型为 {[string]: number} 的对象 o,那么 Object.entries(o) 的参数难道不应该被推断为 [string, number] 吗? - jneuendorf

1
你的问题在于算法,而不是类型。
首先,如果你想让mystring等于"jklasdf",那么你需要像这样访问第一个索引[0]entry[0],因为数组中的第一个元素是对象的键,如果这是你要找的东西的话。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

Object.entries()方法返回一个由给定对象自身的可枚举字符串键属性[key, value]对组成的数组...

因此,无论类型如何,您的代码应该是:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接