You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现递增计数器时遇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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:35:06