TypeScript动态查询执行函数:可选参数的类型校验问题
解决TypeScript通用函数处理带参/无参辅助函数的类型校验问题
问题重现
先看简化后的问题代码:
// 生成查询语句的辅助函数 const foo = (id: number) => `SELECT * FROM table WHERE id = ${id}`; const bar = () => `SELECT * FROM table`; // 初始通用执行函数(类型检查失效) function executeQuery(queryFn: (...args: any[]) => string, ...args: any[]) { return queryFn(...args); } // TS错误:无参函数bar被要求传参 executeQuery(bar); // ❌ Expected 1 arguments, but got 0. // TS无错误:带参函数foo不传参却未触发校验 executeQuery(foo); // ✅ 无报错,但运行逻辑有问题
解决方案:用泛型+内置工具类型实现精准类型匹配
通过TS内置的Parameters<T>工具类型,让通用函数的参数列表严格匹配传入的辅助函数的参数要求:
function executeQuery<T extends (...args: any[]) => string>( queryFn: T, ...args: Parameters<T> ) { return queryFn(...args); }
验证效果
executeQuery(bar); // ✅ 无报错,符合无参函数调用要求 executeQuery(foo); // ❌ TS报错:Expected 1 arguments, but got 0. (正确触发校验) executeQuery(foo, 123); // ✅ 无报错,参数匹配正确
原理说明
- 泛型
T约束为返回string的函数类型,确保传入的是合法的查询生成函数 Parameters<T>是TS内置工具类型,会自动提取泛型T对应的参数元组类型,让args的类型和queryFn的参数完全对齐- 这样TS就能正确校验:无参函数不允许传参,带参函数必须传入对应类型的参数
扩展:支持异步查询函数
如果你的辅助函数是异步返回Promise的,只需调整泛型约束和返回值:
async function executeAsyncQuery<T extends (...args: any[]) => Promise<string>>( queryFn: T, ...args: Parameters<T> ): Promise<string> { return queryFn(...args); }
内容的提问来源于stack exchange,提问作者Killerpixler
相关产品推荐
相关产品推荐

