【问题标题】:Flow typing issue on conditional object property条件对象属性的流类型问题
【发布时间】:2019-12-26 08:08:09
【问题描述】:

我遇到了这个流程问题string [1] is not an object,代码如下:

type User = {
  name: string,
  age: number,
  gender?: string,
}

const user: User = {
  name: 'xxx',
  age: 23,
  ...(props.gender && { gender: props.gender })   // <----- the culprit is this line
}

你知道为什么吗?
对象剩余扩展运算符似乎不正确支持有条件地设置键。

我解决了它:

const user: User = {
  name: 'xxx',
  age: 23,
}
if (props.gender) {
  user.gender = props.gender
}

但我不想放弃基于流输入的语言功能。

【问题讨论】:

  • 请附上一个完整的例子。您的代码在这里可以正常工作:flow.org/try/…

标签: javascript typescript object ecmascript-6 flowtype


【解决方案1】:

通读Github issue on object rest spread operator,我找到了更好的解决方法。这是默认为空对象。

所以我改变了这一行:

...(props.gender && { gender: props.gender })

...((props.gender && { gender: props.gender }) || {})

现在流程错误已解决。

【讨论】:

  • 如果是三元运算符,则改为三元运算符。三元组的推理更简单:...((props.gender ? { gender: props.gender }) : {})
【解决方案2】:

Flow 在您的代码中发现了一个合法的类型错误。如果gender 是一个空字符串,您的代码相当于

const user: User = {
  name: 'xxx',
  age: 23,
  ...""
};

虽然不是运行时错误,但绝对是一个奇怪的类型错误。您应该只在对象上使用对象扩展语法。

这里最好的解决方法是在你完成之后分配属性,或者这样做

...(props.gender ? { gender: props.gender } : null)

其中明确表示“如果性别是虚假的,则不要传播任何属性”。您也可以使用{} 代替null,但这只会无缘无故地创建一个额外的对象。

【讨论】:

  • 感谢您的明确答复。 null vs {} 的好点;)但是,扩展语法应该类似于Object.assign 并且后者将任何原语处理为{},因此它不应该触发流类型错误。但我同意,为了清楚起见,添加三元是一种更易读的方法。谢谢!
  • 您关于gender 是空字符串的评论对我来说似乎不正确。如果gender 是一个空字符串'',它将强制转换为false,因此不会有条件地传播。
  • @DivyanshuMaithani 对象传播使用此处指定的对象强制:ecma-international.org/ecma-262/10.0/index.html#sec-toobject,因此对false 没有强制。
猜你喜欢
  • 1970-01-01
  • 2017-09-14
  • 2023-03-14
  • 2018-06-28
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 2022-06-10
  • 2022-01-23
相关资源
最近更新 更多