实现递增计数器时遇TypeScript报错:无法调用可能为undefined的对象
修复TypeScript中useInterval的"Cannot invoke an object which is possibly 'undefined'"错误
问题代码
function useInterval(callback: any, delay: any) { const savedCallback = useRef(); savedCallback.current = callback; useEffect(() => { savedCallback.current = callback; }, [callback]); useEffect(() => { let id = setInterval(() => { savedCallback.current(); }, delay); return () => clearInterval(id); }, [delay]); } useInterval(() => { setTimer(timer + 1); }, 1000);
报错信息
Cannot invoke an object which is possibly 'undefined'.ts(2722)
(property) MutableRefObject.current: undefined
修复方案
方法1:添加类型定义+空值检查(最安全)
给useRef明确指定类型,初始化时设为null,调用前先判断current是否存在,同时完善参数的类型定义:
import { useRef, useEffect } from 'react'; function useInterval(callback: () => void, delay: number | null) { // 明确ref的类型为回调函数或null const savedCallback = useRef<(() => void) | null>(null); useEffect(() => { savedCallback.current = callback; }, [callback]); useEffect(() => { if (delay === null) return; const id = setInterval(() => { // 调用前检查是否存在,同时消除TS报错和潜在运行时风险 if (savedCallback.current) { savedCallback.current(); } }, delay); return () => clearInterval(id); }, [delay]); } // 使用示例 useInterval(() => { setTimer(timer + 1); }, 1000);
方法2:使用非空断言(简便但需确保逻辑安全)
如果你能确认savedCallback.current在调用时一定不会是undefined,可以用非空断言操作符!告诉TypeScript忽略可能的undefined:
useEffect(() => { const id = setInterval(() => { // 非空断言,强制TS认为current不为空 savedCallback.current!(); }, delay); return () => clearInterval(id); }, [delay]);
注意:这种方法跳过了TS的类型校验,若后续代码逻辑变更导致current为undefined,会引发运行时错误,需谨慎使用。
内容的提问来源于stack exchange,提问作者Mihika
相关产品推荐
相关产品推荐

