TypeScript实现React防抖Hook动态参数函数强类型标注
带强类型校验的防抖Hook实现方案
之前尝试的泛型写法useDebounceVoidFunction<T>(func: (...params: T[])无法生效,核心原因是T[]代表所有元素类型统一的可变长度数组,和函数参数的元组特性(参数个数固定、不同位置参数类型独立)不匹配,TS无法从这种写法里提取到准确的参数类型,最终会推断为unknown。
正确实现是通过泛型捕获传入函数的完整类型,配合TS内置Parameters工具类型提取参数元组,完整保留原函数的参数校验规则,可直接复用的代码如下:
import { useRef, useCallback, MutableRefObject } from 'react'; // 泛型T约束为无返回值的任意函数类型,自动匹配传入func的完整类型签名 export function useDebounceVoidFunction<T extends (...args: any[]) => void>( func: T, timeout: number ): (...args: Parameters<T>) => void { const timer: MutableRefObject<NodeJS.Timeout | undefined> = useRef(); const debouncedFunction = useCallback((...params: Parameters<T>) => { clearTimeout(timer.current); timer.current = setTimeout(() => { func(...params); }, timeout); }, [func, timeout]) return debouncedFunction; }
实现效果
- 传入固定参数数量、固定参数类型的原函数时,返回的防抖函数会完全继承原函数的类型约束:例如传入类型为
(id: number, name: string) => void的函数,返回的防抖函数仅允许传入2个参数,且第一个参数为number类型、第二个为string类型,传参数量错误、类型不匹配都会直接触发TS类型报错。 - 兼容任意参数数量、任意参数类型组合的函数,不需要预先定义固定的参数类型列表。
内容的提问来源于stack exchange,提问作者Sean A.S. Mengis
相关产品推荐
相关产品推荐

