检查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
相关产品推荐
相关产品推荐

