T
T
takoyklasnii2020-01-10 14:28:31
typescript
takoyklasnii, 2020-01-10 14:28:31

Why does the error appear that the type is missing?

There are 3 components: App.tsx, HOC (Crud.tsx), TodoForm.tsx
App.tsx

import * as React from "react";
import Navbar from "./components/Navbar";
import TodoForm from "./components/TodoForm";
import TodoList from "./components/TodoList";
import { ITodo } from "./interfaces";
import Crud from "./components/hoc/Crud";

interface IProps {
  todos: ITodo[];
  add: (title: string) => void;
}

const App: React.FC<IProps> = ({ todos, add }) => {
  return (
    <>
      <Navbar />
      <div className="container">
        <TodoForm add={add} />
        <TodoList todos={todos} />
      </div>
    </>
  );
};

const MemorizedApp = React.memo(Crud(App));

export default MemorizedApp;

TodoForm.tsx
import React from "react";

interface IProps {
  add: (title: string) => void;
}

const TodoForm: React.FC<IProps> = ({ add }) => {
  let text: HTMLInputElement | null;

  function __handlePress(e: React.KeyboardEvent<HTMLInputElement | null>) {
    if (e.key === "Enter") {
      add(text!.value);
      text!.value = "";
    }
  }

  return (
    <div className="input-field" style={{ marginTop: "2rem" }}>
      <input
        ref={node => (text = node)}
        type="text"
        id="title"
        placeholder="пишем тут"
        onKeyPress={__handlePress}
      />
      <label htmlFor="title" className="active">
        Что делаем ?
      </label>
    </div>
  );
};

export default TodoForm;

HOC Crud.tsx
import React from "react";
import axios from "axios";
import { ITodo } from "../../interfaces";

interface IState {
  apiUrl: string;
  todos: ITodo[];
}

const Crud = <T extends object>(Component: React.ComponentType<T>) => {
  class WithCrud extends React.Component<T> {
    state: IState = {
      todos: [],
      apiUrl: "http://localhost:5000/api/todo"
    };

    componentDidMount() {
      this.get();
    }

    get = async () => {
      try {
        const { data } = await axios.get(`${this.state.apiUrl}/get`);

        if (data) {
          this.setState((state: IState) => {
            return (state.todos = data.message);
          });
        }
      } catch (error) {}
    };

    add = async (title: string) => {
      if (title !== "") {
        try {
          const { data } = await axios.post(`${this.state.apiUrl}/create`);
          console.log(data);
        } catch (error) {}
      }
    };

    render() {
      const { ...props } = this.props;

      return (
        <Component add={this.add} todos={this.state.todos} {...(props as T)} />
      );
    }
  }
  return WithCrud;
};

export default Crud;

Compile error:
1IGepihABW61SSMAuujHpXH5IapwJgzAUSrETSli
Type '{}' is missing the following properties from type 'IProps': todos, add
What could be the problem ? If I remove add, then the error disappears, an answer comes from the back with tuduhi and everything works out. Where did I go wrong?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Robur, 2020-01-10
@Robur

Because you set the type of props for WithCrud to be the same as for App.
Make a new props interface for the WithCrud class,
or you can just write And read about generics - you either don't need them here or you need to use them wrong class WithCrud extends React.Component<{}> {

D
Dmitry Belyaev, 2020-01-10
@bingo347

Obviously, the App component expects 2 required props according to this interface:

interface IProps {
  todos: ITodo[];
  add: (title: string) => void;
}

Need or make them optional:
interface IProps {
  todos?: ITodo[];
  add?: (title: string) => void;
}

or transfer to App
ReactDOM.render(
  <App todos={[]} add={(title: string) => console.log(title)} />,
  document.getElementById('root')
);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question