以下是我处理 Electron channel 通信的方式:preload.ts
contextBridge.exposeInMainWorld("myIpcRenderer", {
invoke: (channel: Channel, ...args: any[]) =>
callIpcRenderer("invoke", channel, ...args),
send: (channel: Channel, ...args: any[]) =>
callIpcRenderer("send", channel, ...args),
on: (channel: Channel, ...args: any[]) =>
callIpcRenderer("on", channel, ...args),
});
types.d.ts
interface MyIpcRenderer {
invoke(channel: Channel.ReadFiles, ...args: any[]): Promise<ReadFileResult[]>;
}
MyIpcRenderer
type 在 renderer.ts
中强制正确使用:const files = await window.myIpcRenderer.invoke(Channel.ReadFiles, [
svgPath,
]);
但它并没有强制在
main.ts
中正确使用. ipcMain.handle
指的是一种 Electron 方法,可以接受任何名称的 channel 并返回任何类型的 promise 。ipcMain.handle(
"anychannelnamegoes",
async (_event, paths: string[]): Promise<any> => {
...
}
);
如何重写我的代码以强制执行
main.ts
中的主要用法还有?
最佳答案
我看到有两种方法可以做到这一点。
第一种可能性是在您的 typings.d.ts
中覆盖 Electron 库类型声明。文件:
declare module 'electron' {
export interface IpcMain extends NodeJS.EventEmitter {
handle(
channel: Channel,
listener: (
event: IpcMainInvokeEvent,
...args: any[]
) => Promise<void> | any
): void;
}
}
考虑到 Channel
是一个字符串文字( type Channel = 'channel1' | 'channel2'
),你会得到关于 'channel1'
的建议和 'channel2'
,但初始签名channel: string
仍将被允许,任何字符串都将被接受。我看到的第二种可能性是 package 它,这将提供更好的类型安全性:
const myHandler = (
channel: Channel,
listener: (
event: IpcMainInvokeEvent,
...args: any[]
) => Promise<void> | any
) => ipcMain.handle(channel, listener);
// only 'channel1' and 'channel2' would be accepted
myHandler('channel1', (event) => {});
我想输入当前使用扩展运算符 ...args: any[]
声明的参数在这两种情况下,您都需要明确声明参数:...
listener: (
event: IpcMainInvokeEvent,
arg1: string[],
arg2: boolean,
arg3: number
) => Promise<void> | any
...
关于typescript - 如何使 Electron channel 类型更安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61767919/