【问题标题】:Prop that can be 3 collection types可以是 3 种集合类型的道具
【发布时间】:2018-08-03 18:30:21
【问题描述】:

我正在尝试输入一个 react prop 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;
  }

【问题讨论】:

  • 你好克里斯,欢迎来到堆栈溢出。如果您想为您的问题添加信息,请使用edit 函数而不是评论。
  • 能否请您更新问题,说明在出现错误的代码中如何使用items
  • @frontendgirl 更新!

标签: reactjs flowtype


【解决方案1】:

我最好的建议(主要来自我使用 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 的角度来看,没有理由在 .map 中进行额外的 contentType 检查,这将更直接地处理它现在正在处理的类型。

【讨论】:

    猜你喜欢
    • 2017-04-20
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 2021-05-11
    • 1970-01-01
    相关资源
    最近更新 更多