问题出现在使用React和TypeScript编写的ToDo应用中的属性类型(prop type)。

huangapple go评论173阅读模式
英文:

Problem with prop type in ToDo written in React/TypeScript

问题

ToDoApp组件中,我得到一个带有红色下划线的属性todo,并显示以下信息:

TS2322: Type '{ todo: { id: number; text: string; done: boolean; }; }' is not assignable to type 'IntrinsicAttributes & ToDoItemProps'.
 Property 'todo' does not exist on type 'IntrinsicAttributes & ToDoItemProps'.

我比较了其他人在React/TypeScript中如何处理ToDo,发现它们都是以相同的方式完成的。这可能是我的IDE的问题吗?

英文:

I have a very simple ToDo app composed of two components:

interface ToDoItemProps {
  id: number;
  text: string;
  done: boolean;
}

const ToDoItem = ({ id, text, done }: ToDoItemProps) => {
  return (
    <li key={id}>
      <input type="checkbox" checked={done} />
      {text}
    </li>
  );
};

const TodoApp = () => {
    return (
        <ul>
            {todos.map((todo) => {
                return <ToDoItem todo={todo} />
            })}
        </ul>

    )
};

In ToDoApp component, I get a prop todo with red underline and information that:

TS2322: Type '{ todo: { id: number; text: string; done: boolean; }; }' is not assignable to type 'IntrinsicAttributes & ToDoItemProps'.
  Property 'todo' does not exist on type 'IntrinsicAttributes & ToDoItemProps'.

问题出现在使用React和TypeScript编写的ToDo应用中的属性类型(prop type)。

I compared how others do ToDos in React/TypeScript, and I found it done the same way. Could it be a problem with my IDE?

答案1

得分: 2

接口ToDoItemProps定义了以下属性:idtextdone。它们中没有一个被称为todo

如果这些属性实际上是一个新的ToDo接口的属性,那么我们可以将您的示例重写为:

interface ToDoItemProps {
  todo: ToDo
}

interface ToDo {
  id: number;
  text: string;
  done: boolean;
}
英文:

The interface ToDoItemProps defines the following props: id, text and done. None of them is called todo.

If these props are actually the properties of a new ToDo interface, then we can rewrite your example as:

interface ToDoItemProps {
  todo: ToDo
}

interface ToDo {
  id: number;
  text: string;
  done: boolean;
}

答案2

得分: 0

这是如何编写TodoApp组件的props的方式:

const TodoApp = () => {
    return (
        <ul>
            {todos.map((todo) => {
                return <ToDoItem 
                          id={todo.id}
                          done={todo.done}
                          text={todo.text}
                        />;
            })}
        </ul>
    );
};

或者可以使用展开运算符的方式:

const TodoApp = () => {
    return (
        <ul>
            {todos.map((todo) => {
                return <ToDoItem {...todo} />;
            })}
        </ul>
    );
};
英文:

This how todoApp props should be written

const TodoApp = () =&gt; {
    return (
        &lt;ul&gt;
            {todos.map((todo) =&gt; {
                 return &lt;ToDoItem 
                          id={todo.id}
                          dono={todo.done}
                          text={todo.text}
                        /&gt;}
             }              
        &lt;/ul&gt;

    )
};

or using spread operator

const TodoApp = () =&gt; {
    return (
        &lt;ul&gt;
            {todos.map((todo) =&gt; {
                 return &lt;ToDoItem {...todo} /&gt;        
             }}        
        &lt;/ul&gt;

    )
};

答案3

得分: 0

我通过以下方式解决了我的问题:
根据 @cmolina 的建议,我添加了一个新的接口来定义 ToDoItem,并修正了属性解构。我还为 ToDoItem.tsx 添加了

ToDoInterfaces.ts:

export interface ToDoItemProps {
  id: number;
  text: string;
  done: boolean;
}

ToDoApp.tsx 保持不变:

const ToDoApp = () => {
  return (
    <ul>
      {todos.map((todo) => {
        return <ToDoItem todo={todo} />;
      })}
    </ul>
  );
};

ToDoItem.tsx:

import { ToDoItemProps } from "./ToDoInterfaces";

interface Props {
  todo: ToDoItemProps;
}

const ToDoItem = ({ todo }: Props) => {
  const { id, done, text } = todo;

  return (
    <li key={id}>
      <input type="checkbox" id={`task${id}`} checked={done} />
      <label htmlFor={`task${id}`}>{text}</label>
    </li>
  );
};
英文:

I resolved my issue in the following way:
I added new interface as per @cmolina comment for ToDoItem and I corrected prop destructuring. I also added <label> for accessibility in ToDoItem.tsx

ToDoInterfaces.ts:

export interface ToDoItemProps {
  id: number;
  text: string;
  done: boolean;
}

ToDoApp.tsx was left as it was:

const ToDoApp = () =&gt; {
  return (
    &lt;ul&gt;
      {todos.map((todo) =&gt; {
        return &lt;ToDoItem todo={todo} /&gt;;
      })}
    &lt;/ul&gt;
  );
};

ToDoItem.tsx:

import { ToDoItemProps } from &quot;./ToDoInterfaces&quot;;

interface Props {
  todo: ToDoItemProps;
}

const ToDoItem = ({ todo }: Props) =&gt; {
  const { id, done, text } = todo;

  return (
    &lt;li key={id}&gt;
       &lt;input type=&quot;checkbox&quot; id={`task${id}`} checked={done} /&gt;
       &lt;label htmlFor={`task${id}`}&gt;{text}&lt;/label&gt;
    &lt;/li&gt;
  );
};

huangapple
  • 本文由 发表于 2023年8月11日 00:29:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76877666.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定