在TypeScript中创建电子菜单?

stw*_*sel 10 typescript tsc electron typescript-typings

刚刚使用TypeScript启动了一个简单的Electron应用程序,我正在尝试自定义菜单设置.我按照JS中的例子,但行

menu = Menu.buildFromTemplate(template); 无法编译错误:

main.ts(109,35): error TS2345: Argument of type '({ label: string; submenu: ({ role: string; } | { type: string; })[]; } | { role: string; submenu...' is not assignable to parameter of type 'MenuItemConstructorOptions[]'.

我肯定错过了什么.无法在任何地方找到类型"MenuItemConstructorOptions(但我可能看错了地方).我的main.ts的完整代码:从'电子'导入{app,BrowserWindow,screen,Menu};导入*作为路径来自'路径';

    let win, menu;

    function createWindow() {
        const electronScreen = screen;
        const size = electronScreen.getPrimaryDisplay().workAreaSize;

        win = new BrowserWindow({
            x: 0,
            y: 0,
            width: size.width,
            height: size.height
        });

        // and load the index.html of the app.
        win.loadURL('file://' + __dirname + '/index.html');
        win.webContents.openDevTools();

        win.on('closed', () => {
            win = null;
        });
    }

    function createMenu() {
        const template = [{
                label: 'Edit',
                submenu: [
                    { role: 'undo' },
                    { role: 'redo' },
                    { type: 'separator' },
                    { role: 'cut' },
                    { role: 'copy' },
                    { role: 'paste' },
                    { role: 'pasteandmatchstyle' },
                    { role: 'delete' },
                    { role: 'selectall' }
                ]
            },
            {
                label: 'View',
                submenu: [
                    { role: 'reload' },
                    { role: 'forcereload' },
                    { role: 'toggledevtools' },
                    { type: 'separator' },
                    { role: 'resetzoom' },
                    { role: 'zoomin' },
                    { role: 'zoomout' },
                    { type: 'separator' },
                    { role: 'togglefullscreen' }
                ]
            },
            { role: 'window', submenu: [{ role: 'minimize' }, { role: 'close' }] },
            {
                role: 'help',
                submenu: [{
                    label: 'Learn More',
                    click() {
                        require('electron').shell.openExternal('https://electron.atom.io');
                    }
                }]
            }
        ];

        menu = Menu.buildFromTemplate(template);
        Menu.setApplicationMenu(menu);
    }

    try {
        app.on('ready', function() {
            createWindow();
            createMenu();
        });

        app.on('window-all-closed', () => {
            if (process.platform !== 'darwin') {
                app.quit();
            }
        });

        app.on('activate', () => {
            if (win === null) {
                createWindow();
            }
        });
    } catch (e) {
        throw e;
    }
Run Code Online (Sandbox Code Playgroud)

Pho*_*ixS 17

对我来说足以将模板const的类型设置为Electron.MenuItemConstructorOptions[].

例如:

const template: Electron.MenuItemConstructorOptions[] = [{
        label: 'Edit',
        submenu: [
            { role: 'undo' },
            { role: 'redo' },
            { type: 'separator' },
            { role: 'cut' },
            { role: 'copy' },
            { role: 'paste' },
            { role: 'pasteandmatchstyle' },
            { role: 'delete' },
            { role: 'selectall' }
        ]
    },
    {
        label: 'View',
        submenu: [
            { role: 'reload' },
            { role: 'forcereload' },
            { role: 'toggledevtools' },
            { type: 'separator' },
            { role: 'resetzoom' },
            { role: 'zoomin' },
            { role: 'zoomout' },
            { type: 'separator' },
            { role: 'togglefullscreen' }
        ]
    },
    { role: 'window', submenu: [{ role: 'minimize' }, { role: 'close' }] },
    {
        role: 'help',
        submenu: [{
            label: 'Learn More',
            click() {
                require('electron').shell.openExternal('https://electron.atom.io');
            }
        }]
    }
];
Run Code Online (Sandbox Code Playgroud)


moo*_*e99 6

对我来说,问题是正确的角色大写:

  { role: 'forceReload' },
  { role: 'toggleDevTools' }
Run Code Online (Sandbox Code Playgroud)

超过

  { role: 'forcereload' },
  { role: 'toggledevtools' }
Run Code Online (Sandbox Code Playgroud)

请参阅文档


stw*_*sel 5

我无法在 TS 中获得适用于 JS 的示例。的MenuItemConstructorOptions是中定义的接口electron.d.ts,在电子包文件。但是,我找到了一种解决方法,即分别定义菜单项并将它们推送到一个空数组。有趣的是,里面的子菜单条目被接受并正常工作。这是有效的代码:

  function createMenu() {
     const template = [];
     // Edit Menu
     template.push({
        label: 'Edit',
        submenu: [
           { role: 'undo' },
           { role: 'redo' },
           { type: 'separator' },
           { role: 'cut' },
           { role: 'copy' },
           { role: 'paste' },
           { role: 'pasteandmatchstyle' },
           { role: 'delete' },
           { role: 'selectall' }
        ]
     });
     // View Menu
     template.push({
        label: 'View',
        submenu: [
           { role: 'reload' },
           { role: 'forcereload' },
           { role: 'toggledevtools' },
           { type: 'separator' },
           { role: 'resetzoom' },
           { role: 'zoomin' },
           { role: 'zoomout' },
           { type: 'separator' },
           { role: 'togglefullscreen' }
        ]
     });
     // Windown menu
     template.push({
        role: 'window',
        submenu: [{ role: 'minimize' }, { role: 'close' }]
     });
     // Help menu
     template.push({
        role: 'help',
        submenu: [
           {
              label: 'Learn More',
              click() {
                 require('electron').shell.openExternal('https://electron.atom.io');
              }
           }
        ]
     });

     if (process.platform === 'darwin') {
        template.unshift({
           label: app.getName(),
           submenu: [
              { role: 'about' },
              { type: 'separator' },
              { role: 'services', submenu: [] },
              { type: 'separator' },
              { role: 'hide' },
              { role: 'hideothers' },
              { role: 'unhide' },
              { type: 'separator' },
              { role: 'quit' }
           ]
        });

        // Edit menu
        template[1].submenu.push(
           { type: 'separator' },
           { label: 'Speech', submenu: [{ role: 'startspeaking' }, { role: 'stopspeaking' }] }
        );

        // Window menu
        template[3].submenu = [{ role: 'close' }, { role: 'minimize' }, { role: 'zoom' }, { type: 'separator' }, { role: 'front' }];
     }

     menu = Menu.buildFromTemplate(template);
     Menu.setApplicationMenu(menu);
  }
Run Code Online (Sandbox Code Playgroud)

如果有人在同一问题上绊倒,希望这会有所帮助


jkm*_*ale 5

当我的菜单语法基于 Electron 的Menuexample时,我遇到了同样的错误,它在 JavaScript 中运行良好,但在 TypeScript 中却很糟糕。不幸的是,PhoneixS 所建议的演员MenuItemConstructorOptions[]阵容并不适合我。template

它看起来像 Electron 示例中的三元组上的 TypeScript 行程,并且无法计算出它们的结果类型。就我而言,as MenuItemConstructorOptions[]在包含三元组的右括号后添加使 TypeScript 意识到它们毕竟是有效的子菜单。

有效 TypeScript 中的完整 Electron 示例:

import { app, Menu, MenuItemConstructorOptions, shell } from "electron"

const isMac = process.platform === 'darwin'

const menu = Menu.buildFromTemplate(
  [
    // { role: 'appMenu' }
    ...(isMac ? [{
      label: app.name,
      submenu: [
        { role: 'about' },
        { type: 'separator' },
        { role: 'services' },
        { type: 'separator' },
        { role: 'hide' },
        { role: 'hideothers' },
        { role: 'unhide' },
        { type: 'separator' },
        { role: 'quit' }
      ]
    }] : []) as MenuItemConstructorOptions[],
    // { role: 'fileMenu' }
    {
      label: 'File',
      submenu: [
        isMac ? { role: 'close' } : { role: 'quit' }
      ] as MenuItemConstructorOptions[]
    },
    // { role: 'editMenu' }
    {
      label: 'Edit',
      submenu: [
        { role: 'undo' },
        { role: 'redo' },
        { type: 'separator' },
        { role: 'cut' },
        { role: 'copy' },
        { role: 'paste' },
        ...(isMac ? [
          { role: 'pasteAndMatchStyle' },
          { role: 'delete' },
          { role: 'selectAll' },
          { type: 'separator' },
          {
            label: 'Speech',
            submenu: [
              { role: 'startSpeaking' },
              { role: 'stopSpeaking' }
            ]
          }
        ] : [
          { role: 'delete' },
          { type: 'separator' },
          { role: 'selectAll' }
        ]) as MenuItemConstructorOptions[]
      ]
    },
    // { role: 'viewMenu' }
    {
      label: 'View',
      submenu: [
        { role: 'reload' },
        { role: 'forceReload' },
        { role: 'toggleDevTools' },
        { type: 'separator' },
        { role: 'resetZoom' },
        { role: 'zoomIn' },
        { role: 'zoomOut' },
        { type: 'separator' },
        { role: 'togglefullscreen' }
      ]
    },
    // { role: 'windowMenu' }
    {
      label: 'Window',
      submenu: [
        { role: 'minimize' },
        { role: 'zoom' },
        ...(isMac ? [
          { type: 'separator' },
          { role: 'front' },
          { type: 'separator' },
          { role: 'window' }
        ] : [
          { role: 'close' }
        ]) as MenuItemConstructorOptions[]
      ]
    },
    {
      role: 'help',
      submenu: [
        {
          label: 'Learn More',
          click: async () => {
            await shell.openExternal('https://electronjs.org')
          }
        }
      ]
    }
  ]
)

Menu.setApplicationMenu(menu)
Run Code Online (Sandbox Code Playgroud)