我正在尝试使一个反应道具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;
}
答案 0 :(得分:0)
我最好的建议(主要是根据我在使用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
检查,这将使流程更直接地处理当前正在处理的类型。