typescript 类型'({项目}:PropsWithChildren< TodoProps>)=>元素[]"不能赋给类型“FunctionComponent< TodoProps>”

nkoocmlb  于 2023-01-21  发布在  TypeScript
关注(0)|答案(4)|浏览(220)

我正在学习Typescript-react,我陷入了这个错误Type '({ items }: PropsWithChildren<TodoProps>) => Element[]' is not assignable to type 'FunctionComponent<TodoProps>',我迷失了方向。
完全错误:

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;
xnifntxz

xnifntxz1#

是的,这个错误可能听起来有点混乱--本质上它说在函数组件定义中只能返回一个ReactElement或其等价物JSX.Element,由React.FC类型强制执行。
React Fragmentssolve此限制,因此可以按以下方式编写TodoList

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,类和函数组件都可以返回数组中的多个元素作为呈现输出。目前,TS对于函数组件中返回的数组具有类型不兼容性,因此Fragments提供了一个可行的解决方案(除了类型Assert之外)。

eoigrqb6

eoigrqb62#

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

osh3o9ms

osh3o9ms3#

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

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

然后我意识到**React只期望从它的render方法返回一个值(1个父组件)。**因此我用React.Fragment Package 了 children props,用<></>表示,这解决了我的问题。下面是我的Loading组件示例,希望对其他人有所帮助。

import { FunctionComponent } from "react";

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

ffx8fchx4#

我的问题是,我允许VSCode中的“TypeScript快速修复”向主要功能组件接口添加异步。
const Welcome: React.FC<TProps> = async (props) => {
在移除它之后,
const Welcome: React.FC<TProps> = (props) => {
一切都恢复正常了。

相关问题