如何让TypeScript在使用带约束的部分泛型时不使用默认值
问题解决思路与方案
你遇到的问题根源在于:当显式指定部分泛型参数(这里是T)时,TypeScript会对后续带默认值的泛型参数直接使用默认值,而非从传入的函数参数推导F的类型。同时原代码中F的约束存在循环引用(arg: Parameters<F>),加上默认值(...args: any) => any过于宽松,直接绕过了类型检查。
要实现不指定第二个泛型F,同时让TypeScript从函数参数推导其类型,可以按以下方式修改:
1. 移除F的默认值并修正约束
原代码中F的约束(arg: Parameters<F>) => number属于循环引用,TypeScript无法正确解析,需要换成明确的约束。同时移除F的默认值,强制TypeScript从传入的fn参数推导类型:
// 修正约束并移除F的默认值 const constrainGenericTest = <T extends string, F extends (...args: any[]) => number>(fn: F): F => { return fn; }; // 指定T为string,TypeScript自动推导F为(arg: string) => number constrainGenericTest<string>((arg: string) => arg.length)(1); // 报错:类型'number'不能赋值给类型'string',符合预期
2. 关联T与F的参数类型(可选优化)
如果你的场景中F的参数类型需要和T绑定,可以进一步明确约束,让类型检查更严格:
// 让F的参数类型必须为T const constrainGenericTest = <T extends string, F extends (arg: T) => number>(fn: F): F => { return fn; }; // 指定T为string,F的参数被约束为string类型 constrainGenericTest<string>((arg) => parseInt(arg))(1); // 报错:number类型参数不符合string要求
这样修改后,即使显式指定了T,TypeScript也会从传入的函数参数推导F的具体类型,同时严格执行类型检查,不会再出现传入错误参数不报错的情况。
内容的提问来源于stack exchange,提问作者lehovec
相关产品推荐
相关产品推荐

