reactjs - 可以是 3 种集合类型的道具
问题描述
我正在尝试输入一个items
基于路由参数的反应道具,它可以是 3 种集合类型之一。集合是同质的。
我的类型定义是:items: FaqFields[] | HowToVideoFields[] | GuideFields[],
我在这种道具类型上遇到错误,如下所示:
[flow] property `answer` is missing in `HowToVideoFields` [1] but exists in `FaqFields` [2]. (References: [1] [2])
[flow] property `question` is missing in `HowToVideoFields` [1] but exists in `FaqFields` [2]. (References: [1] [2])
[flow] string literal `howTo` [1] is incompatible with string literal `faq` [2] in property `contentType`. (References: [1] [2])
以下是这些字段形状中的每一个供参考
export type SupportCategories = 'SomeCat' | 'SomeOtherCat';
export type FaqFields = {
answer: string,
category: SupportCategories[],
contentType: 'faq',
id: string,
question: string,
slug: string,
title: string,
};
export type GuideFields = {
category: SupportCategories[],
contentType: 'guide',
id: string,
slug: string,
title: string,
};
export type HowToVideoFields = {
category: SupportCategories[],
contentType: 'howTo',
id: string,
slug: string,
title: string,
youtubeId: string,
};
这是我的使用方式items
renderSupportItems(
items
): ?(Element<typeof Accordion> | Element<typeof Masonry>) {
if (items) {
if (items.every(i => i.contentType === 'faq')) {
return (
<Accordion>
{items.map(({category, question, answer, id}) => (
<Accordion.Item key={id}>
{{
label: (
<Styled.FaqTitleWrapper>
<Styled.FaqEyebrow>
<Text tag="h2" theme="newsBody">
{category.join(' | ')}
</Text>
</Styled.FaqEyebrow>
<Text tag="h2" theme="narrowBodyLarge">
{question}
</Text>
</Styled.FaqTitleWrapper>
),
content: (
<Styled.FaqContent>
<Text tag="p" theme="newsBody">
<Markdown>{answer}</Markdown>
</Text>
</Styled.FaqContent>
),
}}
</Accordion.Item>
))}
</Accordion>
);
}
if (items.every(i => i.contentType === 'guide') || items.every(i => i.contentType === 'howTo')) {
return (
<Masonry>{items.map(i => <SupportCard key={i.id} {...i} />)}</Masonry>
);
}
}
return null;
}
解决方案
我最好的建议(主要来自我使用 flow 的经验)是稍微改变items
使用方式,并做如下的事情:
renderSupportItems(
items
): ?(Element<typeof Accordion> | Element<typeof Masonry>) {
if (items) {
if (items.every(i => i.contentType === 'faq')) {
return (
<Accordion>
{items.map((item) => {
if (item.contentType === 'faq') {
const {category, question, answer, id} = item;
return (<Accordion.Item key={id}>
{{
label: (
<Styled.FaqTitleWrapper>
<Styled.FaqEyebrow>
<Text tag="h2" theme="newsBody">
{category.join(' | ')}
</Text>
</Styled.FaqEyebrow>
<Text tag="h2" theme="narrowBodyLarge">
{question}
</Text>
</Styled.FaqTitleWrapper>
),
content: (
<Styled.FaqContent>
<Text tag="p" theme="newsBody">
<Markdown>{answer}</Markdown>
</Text>
</Styled.FaqContent>
),
}}
</Accordion.Item>
))}
</Accordion>
);
};
return null;
}
if (items.every(i => i.contentType === 'guide') || items.every(i => i.contentType === 'howTo')) {
return (
<Masonry>{items.map(i => <SupportCard key={i.id} {...i} />)}</Masonry>
);
}
}
return null;
}
即使从 javascript 的角度来看,也没有理由进行额外contentType
的检查,.map
这将使流更直接地处理它现在正在处理的类型。
推荐阅读
- python - Python IMAP 语法错误
- .net - 如何使用现有文件创建 ASP NET Web 应用程序
- reactjs - 如何在地图功能中使用 gatsby-plugin-image?
- string - R中部分文本识别的查找和返回结果
- python - 如何将 Vulgar 分数转换为浮点数?
- java - 在使用相似对象的多个服务中重用相似方法的最佳方法是什么?
- assembly - 组装测量用户打字时间
- reactjs - 如何根据当前语言显示不同的组件(React / i18n)
- c++ - 动态创建数组时没有“新”的C++垃圾收集
- node.js - MongoDb 在指定的时间后自动更新数据