React自定义Hook返回类型引发TypeScript报错:This expression is not callable
TypeScript错误修复:表达式不可调用问题
我确认代码功能逻辑无误,但在组件中遇到如下TypeScript错误,请求帮助修复:
错误信息
This expression is not callable. Not all constituents of type 'string | ((sectionName: SetStateAction<string>, status: any) => void)' are callable. Type 'string' has no call signatures.ts(2349) const open: string | ((sectionName: SetStateAction<string>, status: any) => void)
自定义Hook代码
import { useState, SetStateAction } from 'react'; export default function useOpen() { const [isOpened, setIsOpened] = useState("closed"); const open = (sectionName: SetStateAction<string>, status: any) => setIsOpened(status ? sectionName : "closed"); return [isOpened, open]; }
组件代码
export default function Opendiv() { const [ isOpened, open ] = useOpen(); return ( <div> <button type="button" onClick={() => open(item.chapter)} className=""></button> {isOpened === item.chapter && ( <div className="transition-all duration-1000 ease-in-out">Opened div, opened div, opened div</div> )} </div>); }
修复方案
错误原因
TypeScript自动推断useOpen的返回值为数组类型(string | ((sectionName: SetStateAction<string>, status: any) => void))[],导致open被识别为string和函数的联合类型。因为string无法被调用,所以触发报错。
具体修复方式
有两种方法可以解决这个问题:
方法1:使用as const断言返回元组类型
修改自定义Hook,通过as const让TypeScript明确返回的是固定顺序的元组,而非任意数组:
import { useState, SetStateAction } from 'react'; export default function useOpen() { const [isOpened, setIsOpened] = useState("closed"); // 给status添加默认值,适配组件中只传一个参数的调用方式 const open = (sectionName: SetStateAction<string>, status: boolean = true) => setIsOpened(status ? sectionName : "closed"); return [isOpened, open] as const; }
方法2:显式定义返回类型接口
提前定义Hook的返回类型,让TypeScript直接使用该类型进行推断:
import { useState, SetStateAction } from 'react'; // 定义Hook返回的元组类型 type UseOpenReturn = [string, (sectionName: SetStateAction<string>, status?: boolean) => void]; export default function useOpen(): UseOpenReturn { const [isOpened, setIsOpened] = useState("closed"); // 给status添加默认值,适配组件调用 const open = (sectionName: SetStateAction<string>, status: boolean = true) => setIsOpened(status ? sectionName : "closed"); return [isOpened, open]; }
额外优化
组件中调用open时只传入了一个参数,但原Hook的open函数要求两个参数,所以给status添加默认值true,确保调用时参数匹配,避免潜在的运行时问题。
内容的提问来源于stack exchange,提问作者FunDevGirl
相关产品推荐
相关产品推荐

