Electron预加载器中如何为on()事件设置箭头函数类型?
解决Electron-React-Boilerplate中IPC事件的TypeScript类型错误
问题场景
使用electron-react-boilerplate时,通过预加载脚本暴露IPC事件监听方法,主进程向渲染进程发送bt:connected事件并携带字符串参数,JavaScript环境下运行正常,但TypeScript抛出类型错误:
Argument of type '(address: string) => void' is not assignable to parameter of type '(...args: unknown[]) => void'. Types of parameters 'address' and 'args' are incompatible. Type 'unknown' is not assignable to type 'string'.ts(2345)
当前src/renderer/preload.d.ts中on方法的声明为:
on( channel: string, func: (...args: unknown[]) => void ): (() => void) | undefined;
解决方案
核心是给IPC通道定义类型映射关系,让TypeScript能根据通道名自动推断对应参数类型,具体步骤如下:
1. 修改预加载脚本的类型声明文件(preload.d.ts)
先定义合法IPC通道与对应参数的类型映射,再通过泛型重构on方法的类型约束:
// 定义所有IPC通道及其对应参数类型 type IpcChannels = { 'bt:connected': [string]; // 该通道对应单个string类型参数 // 可在此扩展其他通道,例如: // 'bt:disconnected': []; // 无参数的通道 // 'bt:data-received': [number, string]; // 多参数的通道 }; declare global { interface Window { electron: { ipcRenderer: { // 用泛型关联通道名与对应参数类型 on<T extends keyof IpcChannels>( channel: T, func: (...args: IpcChannels[T]) => void ): (() => void) | undefined; }; }; } } export {};
2. 保留预加载脚本的原有逻辑
预加载脚本的JavaScript代码无需修改,类型声明仅用于TypeScript校验:
const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('electron', { ipcRenderer: { on(channel, func) { const validChannels = [ 'bt:connected', // 新增通道时同步更新此处数组 ]; if (validChannels.includes(channel)) { ipcRenderer.on(channel, (event, ...args) => func(...args)); } }, } });
3. 渲染进程中正常使用
现在在渲染进程监听bt:connected事件时,TypeScript会自动推断参数为string类型,不再抛出错误:
window.electron.ipcRenderer.on('bt:connected', (arg: string) => { doStuff(arg); });
额外说明
- 后续新增IPC通道时,只需在
IpcChannels类型中添加对应键值对,并同步更新预加载脚本的validChannels数组,即可保证类型校验与运行时校验一致。 - 该方式还能提供通道名的自动补全,减少拼写错误。
内容的提问来源于stack exchange,提问作者chipimix
相关产品推荐
相关产品推荐

