TypeScript React报This expression is not callable错误排查
问题原因
三个报错全是类型定义写错导致的,没有其他逻辑问题:
- 你定义的
ControllerFN是控制器执行后返回的对象结构,但你直接把这个类型套在了控制器函数本身上面。TS会认为floatingNavbarController就是个存了三个属性的普通对象,根本不是函数,所以既会报「函数不能赋值给对象类型」的TS2322,也会在你调用floatingNavbarController()时报「这个类型没有调用签名」的TS2349。 FloatingNavbarItem组件没有声明Props类型,TS不知道这个组件可以接收iconsList属性,所以报属性不存在的TS2322。
修复方法
1. 改控制器的类型标注
把ControllerFN改成函数类型,明确它是个无参数、返回指定结构对象的函数,不要把返回值结构直接当函数的类型用:
import type { SyntheticEvent } from 'react'; import { useState, useMemo } from 'react'; // 如果你已经在别的地方定义过floatingNavbarItem可以删掉这段 type floatingNavbarItem = { value: string; label: string; icon: React.ReactNode; }; // 修正ControllerFN为函数类型 type ControllerFN = () => { iconsList: floatingNavbarItem[]; value: string; handleChange: (event: SyntheticEvent, newValue: string) => void; }; // 这时候再标注类型就完全匹配了 const floatingNavbarController: ControllerFN = () => { const [value, setValue] = useState('addPlan'); const handleChange = (event: SyntheticEvent, newValue: string) => { setValue(newValue); }; const iconsList: floatingNavbarItem[] = useMemo( () => [ { value: 'addPlan', label: 'addPlan', icon: <FontAwesomeIcon icon={faCirclePlus} />, }, ], [], ); return { iconsList, value, handleChange }; };
嫌单独定义ControllerFN麻烦的话,直接给函数写返回值类型就行,代码更简洁:
const floatingNavbarController = () : { iconsList: floatingNavbarItem[]; value: string; handleChange: (event: SyntheticEvent, newValue: string) => void; } => { // 内部逻辑和之前完全一致,不用改 }
2. 给FloatingNavbarItem补Props类型定义
明确告诉TS这个组件要接收iconsList参数:
import type { FunctionComponent } from 'react'; // 定义组件接收的Props结构 type FloatingNavbarItemProps = { iconsList: floatingNavbarItem[]; }; // 给组件绑定Props类型 const FloatingNavbarItem: FunctionComponent<FloatingNavbarItemProps> = ({ iconsList }) => { // 这里写你原来的组件渲染逻辑,遍历iconsList生成导航项即可 return ( {/* 原有渲染逻辑 */} ); };
改完这两处,所有TS报错都会直接消失,业务逻辑和组件分离的写法本身是没问题的。
内容的提问来源于stack exchange,提问作者palnic
相关产品推荐
相关产品推荐

