react-native - 在 Flow 中打开联合类型
问题描述
此代码使用field.type
which 是一个字符串来确定要呈现的组件。
该SelectOptionsOverlay
组件将呈现CardFormSelectField
( type=="select"
) 及其options
.
CardFormTextAreaOverlay
将呈现CardFormTextAreaField
( type=="textarea"
),并且此组件将永远不会尝试使用options
或任何其他不存在于CardFormTextAreaField
.
export type CardFormSelectField = {
title: string,
type: string,
placeholder: string,
options: string[]
};
export type CardFormTextAreaField = {
title: string,
type: string
};
export type CardFormField = CardFormSelectField | CardFormTextAreaField;
overlay(field: CardFormField): ?(SelectOptionsOverlay | CardFormTextAreaOverlay) {
const props = {...};
switch (field.type) {
case "select":
return <SelectOptionsOverlay {...props} />;
case "textarea":
return <CardFormTextAreaOverlay {...props} />;
}
}
该switch
声明保证了这一切的安全。但是,Flow 并不“知道” switch 语句及其安全优势,因此它抱怨:
Cannot return <SelectOptionsOverlay /> because:
Either React.Element [1] is incompatible with SelectOptionsOverlay [2].
Or React.Element [1] is incompatible with CardFormTextAreaOverlay [2].
[1]
是返回语句,[2]
是函数返回值的类型声明:?(SelectOptionsOverlay | CardFormTextAreaOverlay)
CardFormTextAreaOverlay
第二个 return 语句(for )也有相应的错误。
我实际上很难理解这意味着什么,更不用说是否可以修复它了。
另一方面,我理解得更好,如果我删除 return 语句的类型注释,Flow 只会抱怨 return 语句SelectOptionsOverlay
,抱怨field
prop 可能包含的内容options
以及placeholder
不存在于CardFormTextAreaField
.
确实如此,但 switch 语句应该保护我们在实际返回时不会出现错误的道具。但是你不能打开 FlowType 可以吗?因为 Flow 不是真正的 JS?
解决方案
如果可能并且对您的代码有意义,您可以专门type
为每个CardFormField
. 例如,代替type: string
for CardFormSelectField
,您可以拥有type: "select"
. 这样,Flow 就知道当它进入case "select"
块时,它props
的类型必须是CardFormSelectField
. 目前,Flow 无法将每个case
语句与联合类型中的特定类型相关联。
import React from 'react';
type CardFormSelectField = {|
title: string,
type: "select", // NEW!
placeholder: string,
options: string[]
|};
type CardFormTextAreaField = {|
title: string,
type: "textarea", // NEW!
|};
type CardFormField = CardFormSelectField | CardFormTextAreaField;
function SelectOptionsOverlay(props: CardFormSelectField) {
return "SelectOptionsOverlay";
}
function CardFormTextAreaOverlay(props: CardFormTextAreaField) {
return "CardFormTextAreaOverlay";
}
function Overlay(props: CardFormField) {
switch (props.type) {
case "select":
(props: CardFormSelectField);
return <SelectOptionsOverlay {...props} />;
case "textarea":
(props: CardFormTextAreaField);
return <CardFormTextAreaOverlay {...props} />;
}
}
推荐阅读
- java - 每次我点击 Space 时,Libgdx 跳跃和碰撞方法都不起作用
- python - 在 PPT 占位符中适合图片
- php - 会话变量在每次页面重新加载时销毁
- angular - 在Angular 7中使用变量作为参数的ngx-translate
- javascript - 在表单验证中包含数字签名
- python - Glumpy错误'OSError:[WinError 126]找不到指定的模块'
- python - 为什么 Pexpect 代码没有得到我需要的数据?
- c# - 在项目中允许不安全代码有什么后果吗?
- c# - 为什么 AJAX 调用控制器动作只发送单个值?
- python - Word2Vec:使用 Gensim 上传预训练的 word2vec 文件时收到错误