React+TypeScript传Props报错:Binding element 'todos'隐式'any'类型
解决React+TypeScript子组件Props隐式any类型报错
问题根源
报错的核心原因有两个:
- TodoList组件未显式定义Props类型,TypeScript无法推断
todos的具体类型,默认将其视为any; Todo接口定义在App.tsx组件内部,子组件TodoList.tsx无法访问到这个类型定义。
具体解决步骤
1. 共享Todo类型定义
把Todo接口从App.tsx内部抽离出来,让两个组件都能访问到。有两种常用方式:
方式A:单独创建类型文件
新建types/todo.ts文件存放公共类型:
// types/todo.ts export interface Todo { id: string; title: string | undefined; completed: boolean; }
方式B:在TodoList.tsx中定义并导出
直接在子组件文件中定义并导出类型:
// TodoList.tsx import React from "react"; export interface Todo { id: string; title: string | undefined; completed: boolean; }
2. 给TodoList组件的Props指定类型
给组件接收的props添加类型约束,有两种写法:
写法一:自定义Props接口
// TodoList.tsx import React from "react"; // 若用公共类型文件则导入:import { Todo } from './types/todo'; export interface Todo { id: string; title: string | undefined; completed: boolean; } // 定义组件Props类型 interface TodoListProps { todos: Todo[]; } export default function TodoList({ todos }: TodoListProps) { // 注意:原代码中todos是数组,不能直接访问todos.id,需遍历渲染 return ( <div> {todos.map(todo => ( <div key={todo.id}>{todo.title}</div> ))} </div> ); }
写法二:使用React.FC泛型
// TodoList.tsx import React from "react"; // import { Todo } from './types/todo'; export interface Todo { id: string; title: string | undefined; completed: boolean; } type TodoListProps = { todos: Todo[]; }; export default React.FC<TodoListProps>(({ todos }) => { return ( <div> {todos.map(todo => ( <div key={todo.id}>{todo.title}</div> ))} </div> ); });
3. 修改App.tsx导入Todo类型
删除App.tsx内部的Todo接口,改为导入共享的类型:
// App.tsx import { useState, useRef } from "react"; import { uuid } from "uuidv4"; import TodoList, { Todo } from "./TodoList"; // 若用公共类型文件则导入:import { Todo } from './types/todo'; export default function App() { const [todos, setTodos] = useState<Todo[]>([]); const refTitle = useRef<HTMLInputElement | null>(null); const handleAdd = () => { const title = refTitle.current?.value; setTodos((prevTodos) => { return [...prevTodos, { id: uuid(), title: title, completed: false }]; }); }; return ( <> <TodoList todos={todos} /> <input ref={refTitle} type="text" /> <button onClick={handleAdd}>Add</button> </> ); }
额外提示
原代码中TodoList组件直接写{todos.id}是错误的——todos是数组类型,不能直接访问数组的id属性,必须用map遍历每个todo元素,同时给遍历项加上key属性(用todo的id),符合React列表渲染的规范。
内容的提问来源于stack exchange,提问作者hsl
相关产品推荐
相关产品推荐

