TypeScript函数重载中fooBar函数config参数提示不准确问题求助
TypeScript函数重载中fooBar函数config参数提示不准确问题求助
嘿,这个问题我之前也碰到过,来给你唠唠怎么解决!
其实啊,这都是TypeScript的结构类型系统搞的——它天生是“包容型”的,只要对象能沾点边匹配上类型要求的属性(尤其是用了any的时候,检查会更宽松),额外属性甚至缺了必填属性的情况,在函数重载的参数匹配里可能不会被严格卡到。就像你遇到的:
- 传错误的键时TS能报错,这是字面量的额外属性检查在起作用;
- 但空对象或者带多个键的对象能通过,是因为当前的重载类型只说了“可以有这个键”,没说“不能有其他键”,甚至没严格要求“必须有这个键”。
要解决这个问题,我们得给config加上精确类型约束——既要强制必须存在指定的键,又要禁止出现任何其他额外的键。你可以这么改:
首先可以搞个通用的严格类型工具,这样后续加新的类型也方便复用:
interface Window { fooBar: FooFn } // 生成严格的config类型:只允许指定的键,禁止其他所有键 type StrictConfig<T extends string> = { [K in T]: any } & Record<Exclude<string, T>, never>; interface FooFn { (method: 'event', type: 'view_product', config: StrictConfig<'view_product_key'>): void; (method: 'event', type: 'update_cart', config: StrictConfig<'update_cart_key'>): void; }
要是觉得泛型麻烦,直接写死每个重载的config类型也行:
interface Window { fooBar: FooFn } interface FooFn { (method: 'event', type: 'view_product', config: { view_product_key: any } & Record<string, never>): void; (method: 'event', type: 'update_cart', config: { update_cart_key: any } & Record<string, never>): void; }
现在再测试你那几种情况:
window.fooBar('event', 'view_product', {}):TS会直接报错,提示你缺了view_product_key;window.fooBar('event', 'view_product', { update_cart_key: 1 }):依然会正确报错;window.fooBar('event', 'view_product', { view_product_key: 1 }):正常通过;- 要是你试着重传
{ view_product_key: 1, extra_key: 2 }这种带额外键的对象,TS也会立刻报错,完全符合你想要的“只能有一个指定键”的要求。
备注:内容来源于stack exchange,提问作者v.zdorovcev
相关产品推荐
相关产品推荐

