如何使 Electron 通道类型更安全?

use*_*776 5 typescript electron

以下是我处理 Electron 通道通信的方式:

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),
});
Run Code Online (Sandbox Code Playgroud)

types.d.ts

interface MyIpcRenderer {
  invoke(channel: Channel.ReadFiles, ...args: any[]): Promise<ReadFileResult[]>;
}
Run Code Online (Sandbox Code Playgroud)

MyIpcRenderer类型的强制执行正确的使用renderer.ts

const files = await window.myIpcRenderer.invoke(Channel.ReadFiles, [
  svgPath,
]);
Run Code Online (Sandbox Code Playgroud)

但它并没有强制在main.ts. ipcMain.handle指的是一种电子方法,可以接受任何名称的通道并返回任何类型的承诺。

ipcMain.handle(
  "anychannelnamegoes",
  async (_event, paths: string[]): Promise<any> => {
    ...
  }
);
Run Code Online (Sandbox Code Playgroud)

如何重写我的代码以强制执行主要用法main.ts

Gui*_*ume 2

我看到有两种方法可以做到这一点。

第一种可能性是覆盖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;
  }
}
Run Code Online (Sandbox Code Playgroud)

考虑到这Channel是一个字符串文字 ( type Channel = 'channel1' | 'channel2'),您会得到'channel1'和 的建议'channel2',但初始签名channel: string仍然被允许,并且任何字符串都会被接受。

我看到的第二种可能性是包装它,这将提供更好的类型安全性:

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) => {});
Run Code Online (Sandbox Code Playgroud)

如果您想输入当前使用扩展运算符声明的参数,...args: any[]则您需要在两种情况下显式声明参数:

...
listener: (
  event: IpcMainInvokeEvent,
  arg1: string[],
  arg2: boolean,
  arg3: number
) => Promise<void> | any
...
Run Code Online (Sandbox Code Playgroud)