javascript – Union类型缺少属性
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – Union类型缺少属性,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2855字,纯文字阅读大概需要5分钟。
内容图文
说我有以下类型:
type MessageType = 'example1' | 'example2' | 'example3'
type MessageHead = {
+type: MessageType
}
type BaseBody = {
+payload?: any,
+data?: any
}
type LabelledBody = {
+labelName: string
}
type MessageBody = BaseBody | LabelledBody
type Message = MessageHead & MessageBody
然后我会消费这样的消息:
[{name: 'example1'}, {name: 'potato'}].find(thing => thing.name === message.labelName)
导致以下流程异常:
Cannot get message.labelName because:
? all branches are incompatible:
? Either property labelName is missing in MessageHead [1].
? Or property labelName is missing in BaseBody [2].
? ... 1 more error.
使用类型Message = MessageHead& MessageBody显示为违规类型
我不明白为什么我的Union Type不允许带有labelname的消息?
编辑:Tryflow链接:Tryflow link
解决方法:
您的联合类型允许带有labelname的Message.问题是它还允许没有标签名称的消息.考虑一下你在这一行上的联盟:
type MessageBody = BaseBody | LabelledBody
这意味着MessageBody可以是这样的:
type BaseBody = {
+payload?: any,
+data?: any
}
要么
type LabelledBody = {
+labelName: string
}
更进一步,我们可以执行MessageBody和MessageHead之间的交集,并看到Message的形状可以是以下两种情况之一:
(情况1)
{
+type: MessageType, // From MessageHead
+payload?: any, // From BaseBody
+data?: any // From BaseBody
}
(案例2)
{
+type: MessageType, // From MessageHead
+labelName: string // From LabelledBody
}
因此,当Flow看到您正在访问消息对象的labelName时,它(正确地)认为消息对象可能看起来像情况1(上面).如果我们在case 1中,那么你不能访问labelName,因为它不存在,所以它会抛出一个错误.解决此问题的最简单方法是创建两种类型的消息,一种具有labelName,另一种具有有效负载和数据属性.然后,您可以将您的函数注释为接收以下类型之一:
(Try)
type MessageWithLabel = MessageHead & LabelledBody
const exFunc = (message: MessageWithLabel) => {
[{name: 'example1'}, {name: 'potato'}].find(thing => thing.name === message.labelName)
}
或者,您可以使用disjoint union告诉流程您使用的是哪种情况.该策略涉及设置一个属性(例如类型),该属性告诉流程我们正在处理哪种类型的对象.
(Try)
type MessageWithBody = {|
+type: 'base',
+payload?: any,
+data?: any
|}
type MessageWithLabel = {|
+type: 'labelled',
+labelName: string
|}
type Message = MessageWithBody | MessageWithLabel
const exFunc = (message: Message) => {
if (message.type === 'labelled') {
const labelName = message.labelName
return [{name: 'example1'}, {name: 'potato'}].find(thing => thing.name === labelName)
// Sidenote:
// I had to extract labelName to a constant for Flow to typecheck this correctly.
// So if we used thing.name === message.labelName Flow will throw an Error.
// If you don't extract it right away, flow thinks the Message may have changed
// after pretty much any non-trivial action. Obviously it doesn't change in this
// example, but, hey, Flow isn't perfect.
// Reference: https://flow.org/en/docs/lang/refinements/#toc-refinement-invalidations
} else {
// Do something for the 'base' type of message
}
}
内容总结
以上是互联网集市为您收集整理的javascript – Union类型缺少属性全部内容,希望文章能够帮你解决javascript – Union类型缺少属性所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。