英文:
Problem with prop type in ToDo written in React/TypeScript
问题 {#heading}
在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'.
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 {#1}
得分: 2
接口ToDoItemProps
定义了以下属性:id
、text
和done
。它们中没有一个被称为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 {#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 = () => {
return (
<ul>
{todos.map((todo) => {
return <ToDoItem
id={todo.id}
dono={todo.done}
text={todo.text}
/>}
}
</ul>
)
};
or using spread operator
const TodoApp = () => {
return (
<ul>
{todos.map((todo) => {
return <ToDoItem {...todo} />
}}
</ul>
)
};
答案3 {#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 = () => {
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>
);
};
`