如何为Electron的invoke追加类型,无泛型时参数不符也触发报错
问题原因
你的写法不生效是TypeScript重载匹配规则导致的:
- 重载按照从上到下的优先级匹配,命中第一个符合规则的重载就会停止校验
- Electron自带的通用
invoke重载(支持任意string类型channel、任意入参)优先级比你自定义的get专属重载更高,当你不传泛型时,invoke('get', 'response-channel')会直接命中通用重载,不会触发参数校验 - 只有当你传入泛型参数时,无泛型定义的通用重载无法匹配,才会走到你写的专属重载触发参数校验
解决方案
通过「专属重载前置+通用重载排除get场景」的写法,强制所有channel="get"的调用只能命中你定义的专属重载,无论是否传泛型都会校验参数:
declare namespace Electron { interface IpcRenderer { // 1. 优先放最具体的get专属重载 invoke<T = any>(channel: 'get', responseChannel: string, url: string): Promise<T> // 2. 再放通用重载,明确排除channel为get的场景,避免get请求命中通用规则 invoke(channel: Exclude<string, 'get'>, ...args: any[]): Promise<any>; } } class TestClass { ipcRenderer!: Electron.IpcRenderer myFunc() { // 现在会正常抛出参数数量错误 this.ipcRenderer.invoke('get', 'response-channel') // 传泛型的场景也会正常抛出错误,符合预期 this.ipcRenderer.invoke<string>('get', 'response-channel') // 正常的三参数调用不会报错 this.ipcRenderer.invoke('get', 'response-channel', 'https://example.com') // 其他channel的调用不受影响 this.ipcRenderer.invoke('other-channel', 'any', 'params', 'you', 'want') } }
这种写法彻底切断了get请求命中通用重载的可能,不管是否传入泛型,只要第一个参数是get,就会强制匹配你的专属重载,严格校验参数数量必须为3。
内容的提问来源于stack exchange,提问作者Get Off My Lawn
相关产品推荐
相关产品推荐

