【问题标题】:Flow allow concatenation with object.entries and stringFlow 允许与 object.entries 和 string 连接
【发布时间】:2019-10-22 10:35:19
【问题描述】:

我有一个这样的类型:

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] 与字符串不兼容

关于如何解决这个问题的任何想法?谢谢!

【问题讨论】:

  • 奇怪,当我在flow.org/try输入你的代码时,它说没有错误。
  • 根据 Flow 的核心类型,Object.entries 的结果是Array<[string, mixed]>,因此访问entry[0] 应该产生string (reference)。也许您正在尝试访问entry[1](类型为mixed)?
  • 谢谢@user11307804!事实上,我正在访问 entry[1]!
  • @RyanZ,如果您仍然遇到此问题,请参阅 github.com/facebook/flow/issues/2221

标签: javascript flowtype


【解决方案1】:

Object.entries 输入为:

静态条目(对象:$NotNullOrVoid):数组

当您尝试使用 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 完全不安全,应尽可能避免使用。

DEMO

【讨论】:

  • 为什么Object.entries 不使用像Object.fromEntries 这样的泛型类型?如果{[string]: number} 类型的对象o 不应该将Object.entries(o) 的参数推断为[string, number]
【解决方案2】:

您的问题在于算法,而不是类型。

首先,如果你想让mystring等于"jklasdf",那么你需要像entry[0]这样访问第一个索引[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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-14
    • 2017-10-01
    • 2013-06-07
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    相关资源
    最近更新 更多