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

检查ref是否为函数后,TypeScript为何仍报错?

问题

我的ref类型为ForwardedRef<HTMLAudioElement>,其类型定义如下:

type ForwardedRef<T> = ((instance: T | null) => void) | MutableRefObject<T | null> | null;

我在代码中通过typeof ref === 'function'判断ref是否为函数类型,但TypeScript仍在else if块中报错:

const callbackRef = useCallback((node: HTMLAudioElement | null) => {
    if (node && typeof ref === 'function') {
      ref(node);
    } else if (ref) {
      node.volume = volume;
      ref.current = node; // 此处触发TypeScript错误
    }
}, [volume]);

报错信息:

Property 'current' does not exist on type '((instance: HTMLAudioElement | null) => void) | MutableRefObject<HTMLAudioElement | null>'.
  Property 'current' does not exist on type '(instance: HTMLAudioElement | null) => void'.ts(2339)

我可以用类型断言(ref as MutableRefObject<HTMLAudioElement>).current绕过错误,但这样之前的函数检查就失去了意义,这是为什么?

原因与解决方案

原因

TypeScript的类型收窄机制依赖明确的类型特征判断:

  • typeof ref === 'function'确实能排除联合类型中的函数类型,但剩下的非null值,TypeScript无法自动推断它就是MutableRefObject——尽管ForwardedRef的类型定义里只有这三种情况,但TypeScript的结构化类型系统需要明确的结构检查(比如判断对象是否包含current属性),才能确定它符合MutableRefObject的接口。

解决方案

在else if块中增加'current' in ref的检查,让TypeScript明确收窄类型到MutableRefObject,同时修复node可能为null的潜在问题,还要把ref加入useCallback的依赖数组:

import { MutableRefObject, useCallback } from 'react';

const callbackRef = useCallback((node: HTMLAudioElement | null) => {
    if (node && typeof ref === 'function') {
      ref(node);
    } else if (ref && 'current' in ref) {
      if (node) {
        node.volume = volume;
      }
      ref.current = node;
    }
}, [volume, ref]);

这样既保留了类型安全的检查,又能让TypeScript正确识别ref的类型,无需使用类型断言。

内容的提问来源于stack exchange,提问作者wyc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:41:03