【问题标题】:Type '({ items }: PropsWithChildren<TodoProps>) => Element[]' is not assignable to type 'FunctionComponent<TodoProps>'类型 '({ items }: PropsWithChildren<TodoProps>) => Element[]' 不可分配给类型 'FunctionComponent<TodoProps>'
【发布时间】:2020-03-12 20:36:06
【问题描述】:

我正在学习 Typescript-react,但我陷入了这个错误 Type '({ items }: PropsWithChildren&lt;TodoProps&gt;) =&gt; Element[]' is not assignable to type 'FunctionComponent&lt;TodoProps&gt;',我对此迷失了。

完全错误:

Type '({ items }: PropsWithChildren<TodoProps>) => Element[]' is not assignable to type 'FunctionComponent<TodoProps>'.
  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

代码链接:sandbox repo

TodoList.tsx 文件中声明TodoList 函数时发生错误。

感谢任何帮助。干杯!


代码:

import React from "react";

interface Todo {
  id: number;
  content: string;
  completed: boolean;
}

interface TodoProps {
  items: Todo[];
}

//    v------v here is error
const TodoList: React.FC<TodoProps> = ({ items }) => {
  return items.map((item: Todo) => <div key={item.id}>{item.id}</div>);
};

export default TodoList;

【问题讨论】:

    标签: reactjs typescript react-typescript


    【解决方案1】:

    是的,这个错误可能听起来有点令人困惑 - 本质上它表示您只能在函数组件定义中返回单个 ReactElement 或其等效的 JSX.Element,由 React.FC 类型强制执行。

    React Fragmentssolve这个限制,所以可以写TodoListin the following manner

    interface TodoProps {
      items: Todo[];
    }
    
    const TodoList: React.FC<TodoProps> = ({ items }) => (
      <React.Fragment>
        {items.map((item: Todo) => (
          <div key={item.id}>{item.id}</div>
        ))}
      </React.Fragment>
    );
    
    简写:
    const TodoList: React.FC<TodoProps> = ({ items }) => (
      <>
        {items.map(({ id }) => <div key={id}>{id}</div>)}
      </>
    );
    

    顺便说一句:使用纯JS,类和函数组件都可以返回 multiple elements in an array作为渲染输出。目前,TS 有一个type incompatibility 用于函数组件中的返回数组,因此 Fragments 在这里提供了一个可行的解决方法(除了type assertions)。

    【讨论】:

    • 这就是我讨厌TS的原因
    • 听起来我与 ol' JS Date API 的关系(; 。让我们保持积极态度,等待#21699 的修复(这也解释了上述行为的历史原因)
    【解决方案2】:

    我遇到了类似的错误。最终,我注意到在使用 TypeScript 将组件转换为 FunctionComponent 时,我错误地将文件从 .js 重命名为 .ts 而不是 .tsx。

    【讨论】:

      【解决方案3】:

      当我尝试从我的 Loading 组件返回 children 道具时,我也遇到了这个错误,如下所示。

      
          const { loading, children } = props;
          return loading ? <p>Loading ... </p> : children;
      
      

      然后我意识到 React 只期望其 render 方法的一个返回值(1 个父组件)。因此我用 React.Fragment 包装了 children 道具由&lt;&gt;&lt;/&gt; 表示,这解决了我的问题。下面是我的Loadingcomponent 示例,希望对其他人有所帮助。

      import { FunctionComponent } from "react";
      
      interface ILoadingProps {
        loading: boolean;
      }
      export const Loading: FunctionComponent<ILoadingProps> = (props) => {
        const { loading, children } = props;
        return loading ? <p>Loading ... </p> : <>{children}</>;
      };
      
      

      【讨论】:

        猜你喜欢
        • 2019-12-30
        • 2021-01-02
        • 2018-12-09
        • 1970-01-01
        • 2019-12-01
        • 2020-07-04
        • 1970-01-01
        • 2020-08-25
        • 1970-01-01
        相关资源
        最近更新 更多