如何限制TypeScript回调函数参数禁止使用unknown类型
如何禁止TypeScript回调函数使用unknown类型参数并保留合法情况
现有代码:
const any = (any?: any): any => any; export type Fn = (cb: (...args: (string | number)[]) => any) => any; const Fn: Fn = any(); const t1 = Fn((x: unknown) => x); // 当前允许通过,需禁止 const t2 = Fn(<X>(x: X) => x); // 当前允许通过,需禁止
需求:禁止回调函数中使用unknown类型的参数,同时避免出现无约束的泛型参数。
已尝试但无效的方法:
- 在
tsconfig.json中设置strictFunctionTypes - 使用Exact工具类型
- 在cb声明中使用泛型
应当被允许的合法情况:
const t3 = Fn((a: string, b: number) => {}); const t4 = Fn(() => {}); const t5 = Fn((x: string | number, y: string) => {}); const t6 = Fn(<X extends number>(x: X) => x); const t7 = Fn(<X extends string, Y extends string>(x: X, y: Y) => x + y);
目前上述合法情况多数无法正常通过,该如何解决?
解决方案
通过约束回调函数的参数类型,结合TypeScript的泛型与条件类型,可以精准区分合法与非法情况,实现需求:
// 工具类型:仅保留 string | number 子集,排除 unknown type AllowedParam<T> = T extends string | number ? T : never; // 重新定义 Fn 类型,对每个参数做约束 export type Fn = <Args extends unknown[]>( cb: (...args: { [K in keyof Args]: AllowedParam<Args[K]> }) => any ) => any; const any = (any?: any): any => any; const Fn: Fn = any(); // 非法情况(触发报错) const t1 = Fn((x: unknown) => x); // ❌ unknown 不属于允许类型 const t2 = Fn(<X>(x: X) => x); // ❌ 无约束泛型不满足条件 // 合法情况(正常通过) const t3 = Fn((a: string, b: number) => {}); // ✅ const t4 = Fn(() => {}); // ✅ const t5 = Fn((x: string | number, y: string) => {}); // ✅ const t6 = Fn(<X extends number>(x: X) => x); // ✅ const t7 = Fn(<X extends string, Y extends string>(x: X, y: Y) => x + y); // ✅
原理说明
- AllowedParam工具类型:通过条件类型过滤掉
unknown及非string | number的类型,仅保留合法参数类型。 - Fn泛型约束:捕获回调的参数列表,通过映射类型对每个参数逐一校验,确保符合AllowedParam的要求。
- 无约束泛型拦截:无约束的泛型
X无法匹配AllowedParam,会返回never,导致参数类型不匹配触发错误。
注意:需确保tsconfig.json中启用strict: true(至少包含strictFunctionTypes),保证类型检查生效。
内容的提问来源于stack exchange,提问作者Janek Eilts
相关产品推荐
相关产品推荐

