React自定义hook触发onClick事件TypeScript类型错误如何解决
错误原因
TypeScript默认会将未标注类型的数组返回值推断为联合类型数组,也就是你的useCounter返回值被推断为(number | () => void)[]类型,数组内所有元素的类型都是number | 无返回值函数的联合类型。
所以你在组件中解构赋值时,handleIncrement、handleDecrement、reset三个变量的类型都被推断为number | () => void,自然无法直接赋值给只接受函数类型的onClick属性,就触发了第一个编译错误。
你之前写的onClick={() => handleIncrement}虽然绕开了类型校验,但你只在箭头函数里返回了函数引用,没有执行这个函数,所以点击没有任何响应。如果强行改成onClick={() => handleIncrement()},TypeScript会因为无法确定变量是函数还是数字,抛出"表达式不可调用"的第二个错误。
修复方案
有两种常用的修复方式,任选其一即可:
方案1:使用const断言(最简方案)
只需要修改NCounterHook.ts的return语句,给返回的数组添加as const后缀,告诉TypeScript这是一个固定长度、固定类型顺序的只读元组,不要做宽泛的联合类型推断:
// NCounterHook.ts 末尾修改为 return [counter, handleIncrement, handleDecrement, reset] as const;
修改完成后,组件内的原有代码不需要任何改动,onClick={handleIncrement}的写法就能正常通过类型校验,点击事件也能正常触发。
方案2:显式声明hook返回值类型(更易维护)
如果自定义hook逻辑比较复杂,推荐显式声明返回值类型,可读性和可维护性更高:
// NCounterHook.ts 顶部先定义返回值类型 type UseCounterReturn = [ counter: number, handleIncrement: () => void, handleDecrement: () => void, reset: () => void ]; // 给hook函数添加返回值类型标注 const useCounter = (initValue = 0): UseCounterReturn => { // 原有逻辑保持不变 const [counter, setCounter] = useState(0); const handleIncrement = () => { console.log('handleIncrement clicked'); setCounter((prevCounter) => prevCounter + 1); }; const handleDecrement = () => { console.log('handleDecrement clicked'); setCounter((prevCounter) => prevCounter - 1); }; const reset = () => setCounter(initValue); return [counter, handleIncrement, handleDecrement, reset]; };
内容的提问来源于stack exchange,提问作者Ryan Kim
相关产品推荐
相关产品推荐

