如何在ag-grid+React场景下实现强类型的useDynamicCallback
TypeScript版强类型useDynamicCallback实现
最终实现代码
import { useRef, useCallback } from 'react'; function useDynamicCallback<T extends (...args: any[]) => any>(callback: T): T { const callbackRef = useRef<T>(callback); callbackRef.current = callback; return useCallback((...args: Parameters<T>) => { return callbackRef.current(...args); }, []) as T; }
如果需要完全对齐官方JS示例的apply和this绑定逻辑,可以用以下版本:
import { useRef, useCallback } from 'react'; function useDynamicCallback<T extends (...args: any[]) => any>(callback: T): T { const callbackRef = useRef<T>(callback); callbackRef.current = callback; return useCallback(function(this: any, ...args: Parameters<T>) { return callbackRef.current.apply(this, args); }, []) as T; }
实现说明
- 泛型约束:通过
T extends (...args: any[]) => any捕获传入回调的完整函数类型,同时限制入参必须为函数类型 - Ref类型固定:初始化
useRef时直接指定泛型为T,避免ref类型被推导为T | undefined,无需后续any断言 - 类型自动适配:使用TS内置工具类型
Parameters<T>自动匹配原回调的参数列表类型,返回值自动继承原回调的返回值类型 - 安全类型断言:最终返回的函数参数、返回值都和原回调完全一致,
as T的断言完全安全,不会出现类型不匹配问题
使用示例
在ag-grid场景下的使用样例:
import { ColDef } from 'ag-grid-community'; // 定义单元格点击回调 const handleCellClick = (params: ColDef['cellRendererParams']) => { console.log('当前行数据', params.data); }; // 得到的dynamicClickHandler类型和原handleCellClick完全一致 const dynamicClickHandler = useDynamicCallback(handleCellClick); // 直接传入ag-grid列配置,无需额外类型适配 const columnDefs: ColDef[] = [ { field: 'username', headerName: '用户名', cellRenderer: dynamicClickHandler } ];
内容的提问来源于stack exchange,提问作者arunmmanoharan
相关产品推荐
相关产品推荐

