Electron渲染进程中TypeScript4.1.2扩展window.Notification处理点击事件
解决Electron渲染进程中TypeScript 4下扩展window.Notification点击事件的问题
我明白你遇到的困扰了——之前在TS2里能正常运行的函数式代理写法,升级到TS4后突然失效,尝试类继承也没搞定。这主要是因为TS4对DOM类型的检查更严格,再加上Electron原生Notification的特殊性导致的,下面给你几个可行的解决方案:
方案1:修复函数式代理写法(最贴近你原来的思路)
原来的写法其实藏着一个关键问题:你的ProxyNotification函数没有返回创建的原生通知实例,TS2里可能没被严格校验,但TS4的类型系统会直接报错,而且实际运行时也得不到有效的通知对象。修正后的代码如下:
const nativeNotification = window.Notification; // 定义符合NotificationConstructor类型的代理函数 const ProxyNotification: NotificationConstructor = function(title: string, options?: NotificationOptions) { const mirrorNotification = new nativeNotification(title, options); // 绑定点击事件,同时保留原有逻辑(如果有的话) const originalOnClick = mirrorNotification.onclick; mirrorNotification.onclick = (event) => { console.log("NOTIFICATION CLICKED!", event); if (originalOnClick) { originalOnClick.call(mirrorNotification, event); } }; // 核心:必须返回原生通知实例,否则创建的通知会无效 return mirrorNotification; } as any; // 用as any绕过TS对函数式构造器和类构造器的类型差异检查 // 拷贝所有静态属性和方法(比如权限相关的属性和方法) ProxyNotification.permission = nativeNotification.permission; ProxyNotification.requestPermission = nativeNotification.requestPermission; // 拷贝其他可能存在的静态属性(比如maxActions) if ('maxActions' in nativeNotification) { (ProxyNotification as any).maxActions = nativeNotification.maxActions; } // 替换原生Notification window.Notification = ProxyNotification;
方案2:用Proxy包装原生构造器(更简洁优雅)
Proxy可以自动代理所有静态属性和方法,不需要手动逐个拷贝,代码更清爽:
const nativeNotification = window.Notification; window.Notification = new Proxy(nativeNotification, { // 拦截实例创建过程 construct(target, args) { const instance = new target(...args); // 用addEventListener绑定点击事件,避免覆盖原有onclick逻辑 instance.addEventListener('click', (event) => { console.log("NOTIFICATION CLICKED!", event); }); // 如果你需要覆盖onclick而非追加事件,可以用下面的写法: // const originalOnClick = instance.onclick; // instance.onclick = (event) => { // console.log("NOTIFICATION CLICKED!", event); // originalOnClick?.call(instance, event); // }; return instance; }, // 自动代理所有静态属性和方法 get(target, prop) { return target[prop as keyof typeof target]; } }) as NotificationConstructor;
为什么你之前的类继承写法失效?
你之前的类写法犯了一个核心错误:在constructor里先创建了一个nativeNotification实例,然后又调用super()创建了另一个全新的实例——实际使用的是super()返回的那个实例,而你绑定点击事件的是第一个实例,自然不会触发任何逻辑。
就算你去掉第一个实例,直接在super()后修改this.onclick,在Electron里也可能因为原生Notification的底层实现机制,导致继承类的实例事件无法正确被捕获。所以用Proxy或者函数包装的方式会更可靠。
内容的提问来源于stack exchange,提问作者Nameless
相关产品推荐
相关产品推荐

