reactjs - 类型 '(props: Props) => Element[]' 不可分配给类型 'FunctionComponent<Props>'

标签 reactjs typescript

我正在尝试在 React 应用程序中添加 TypeScript。

版本:

"react": "16.9.0",
"typescript": "3.5.3",

我有一个像这样的数组

import aLogo from '../images/a.svg';
import bLogo from '../images/b.svg';

const websites = [
  {
    name: 'A',
    src: aLogo,
    url: 'https://a.com',
  },
  {
    name: 'B',
    src: bLogo,
    url: 'https://b.com',
  },
];

我通过 props 将它传递给组件。

interface Website {
  name: string;
  src: string;
  url: string;
}

interface Props {
  websites: Website[];
}

const SocialList: React.FC<Props> = (props: Props) => {
  const { websites } = props;

  return websites.map((website) => {
    const { name, src, url } = website;

    return (
      <a key={name} href={url}>
        <img src={src} />
      </a>
    );
  });
};

但是它给了我错误

TypeScript error in /SocialList.tsx(16,7):
Type '(props: Props) => Element[]' is not assignable to type 'FunctionComponent<Props>'.
  Type 'Element[]' is missing the following properties from type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>': type, props, key  TS2322

    14 | }
    15 | 
  > 16 | const SocialList: React.FC<Props> = (props: Props) => {
       |       ^

我阅读了 how do you declare an array of objects inside typescript? 中的答案,但仍然不知道如何修复它。

最佳答案

您的 SocialList 组件呈现多个节点。虽然 React 版本 >=16.0 支持此行为,但 React 的类型声明 (@types/react) 不允许这种行为。换句话说,在 JS React (v16+) 中可以渲染多个节点,但在 TS React 中则不行。对于JS React,请参阅相关问题:Return multiple elements inside React.render() .

要解决此问题,您有几个选择:更新组件以使其仅返回单个节点、使用类型断言或禁用 TypeScript 中的错误。

返回单个节点

您可以更新代码以返回包含元素中的 a 标记。过去默认使用 div,但这会使 DOM 变得困惑。相反,您可以使用 React.Fragment组件,它不会向实际 DOM 渲染任何内容,因此基本上就是您所追求的。

示例:

const SocialList: React.FC<Props> = (props: Props) => {
  const { websites } = props;

  const websiteElements = websites.map((website) => {
    const { name, src, url } = website;

    return (
      <a key={name} href={url}>
        <img src={src} />
      </a>
    );
  });

  return (
    <React.Fragment>
      {websiteElements}
    </React.Fragment>
  )
};

您还可以使用short syntax for fragments如果您愿意,如下所示:

<>
  {websiteElements}
</>

类型断言

您可以断言返回值的类型为any,这将导致类型错误被忽略。然而,这将与 eslint 规则 no-explicit-any 发生冲突。如果您启用了该功能(这是我不同意的规则)。无论如何,我不推荐这种方法,因为您应该尽可能避免asany(这里是可以避免的)。

示例:

const SocialList: React.FC<Props> = (props: Props) => {
  const { websites } = props;

  return websites.map((website) => {
    const { name, src, url } = website;

    return (
      <a key={name} href={url}>
        <img src={src} />
      </a>
    );
  }) as any;
};

禁用错误

由于错误只是由于 @types/react 的类型声明造成的,因此您可以 suppress the TS error//@ts-ignore 放在错误行上方。您可以尝试找到要忽略的更具体的错误,但在这种情况下我找不到它,所以要小心,因为这将忽略该行上的所有 TS 错误(例如,如果 Props 接受类型参数,但未给出类型参数)。

我不推荐这种方法,因为应尽可能避免禁用 TS 错误,并且来自the TypeScript docs :

Please note that this comment only suppresses the error reporting, and we recommend you use this comments very sparingly.

示例:

// @ts-ignore
const SocialList: React.FC<Props> = (props: Props) => {
  const { websites } = props;

  return websites.map((website) => {
    const { name, src, url } = website;

    return (
      <a key={name} href={url}>
        <img src={src} />
      </a>
    );
  });
};

关于reactjs - 类型 '(props: Props) => Element[]' 不可分配给类型 'FunctionComponent<Props>',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57651621/

相关文章:

javascript - $digest 之后值变得未定义

javascript - 使用字符串数组作为路径动态访问嵌套对象

reactjs - React 事件处理程序中带有 Typescript 的动态对象键

javascript - 如何测试在 componentDidMount 中设置 React Component 状态的异步调用

javascript - 未捕获的类型错误 : Cannot read property 'data' of undefined with Gatsby and graphQl

javascript - 取消拖动或禁用重新排序

javascript - 将辅助数据传递给我的第二个回调函数

javascript - 如何在 Angular2 中从一个组件连接到另一个组件

javascript - VS 代码 - 无法隐藏从 typescript 文件生成的 javascript 文件

javascript - 需要在 Antd Datepicker 中编辑 Moment 以显示月份的全名