使用Typescript进行反应:Type Missmatch

时间:2019-04-12 10:56:28

标签: reactjs typescript mobx-react react-tsx

有一段时间开始将React与Typescript一起使用,但总是与类型和React元素的期望混淆。

像在这种情况下一样(也sandbox here),我得到了Todos组件的以下错误

  

在具有更漂亮和TSLint设置的VSCODE中:类型'(props:PropsWithChildren)=>元素[]'不能分配给'FunctionComponent'类型。

     
    

在Snadbox中:类型'(props:IProps)=> void []'不能分配给'FunctionComponent'类型。

  

    import { TodoStore } from "./stores/TodoStore";
    import { observable } from "mobx";
    interface IProps {
      todoStore: TodoStore;
    }
   // red underline at `TodoComp` with mentioned error message
    const TodosComp: React.FC<IProps> = props => {
      const { todos } = props.todoStore;
      return todos.map(todo => {
        <div key={todo.id}>
          <p>{todo.title}</p>
          <select />
        </div>;
      });
    };
    export default inject("todoStore")(observer(TodosComp));

待办事项的Mobx商店就像

import { decorate, observable, runInAction, action } from 'mobx';
export interface ITodo {userId: number; id: number; title: string; completed: boolean;
}
export class TodoStore {
  public todos: ITodo[];
  constructor() {
    this.todos = [];
    this.fetchTodos();
  }

  public async fetchTodos() {
    const response = await fetch('http://jsonplaceholder.typicode.com/todos');
    const todos: ITodo[] = await response.json();
    runInAction(() => {
      this.todos = todos;
    });
 }}
decorate<TodoStore>(TodoStore, { todos: observable, fetchTodos: action });

Mobx是问题所在,并且类本身是否用作组件中的类型? mobx类是否需要单独的接口?

作为Mobx特有的问题,沙盒中在提供程序上实例化商店类的方法是否正确?

通常,如果有人对打字稿中关于React的文章有很好的了解,那么如何管理道具和JSX类型将不胜感激。

2 个答案:

答案 0 :(得分:1)

函数应该返回JSX.Element,并且您需要传递div或Fragment,这应该可以工作。

const Todos: React.FC<IProps> = (props: IProps): JSX.Element => {
  const { todos } = props.todoStore;
  return (<React.Fragment>
    {todos.map(todo => {
      <div key={todo.id}>
        <p>{todo.title}</p>
        <select />
      </div>;
    })}
  </React.Fragment>);
};

答案 1 :(得分:1)

FunctionComponent定义为

interface FunctionComponent<P = {}> {
  (props: PropsWithChildren<P>, context?: any): ReactElement | null;
  ...

ReactElement在哪里

interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
  type: T;
  props: P;
  key: Key | null;
}

通过查看这些定义,您可以知道您无法从React.FC返回数组。解决方案是将您的返回值包装在类似React的片段中

return (
  <>
    {todos.map(todo => {
      <div key={todo.id}>
        <p>{todo.title}</p>
        <select />
      </div>;
    })}
  </>
);