Browse Source

refactor: replace a few any-s with proper types (#25681)

Milan Burda 4 years ago
parent
commit
fb11a12d5b

+ 3 - 3
lib/asar/fs-wrapper.ts

@@ -7,15 +7,15 @@ const v8Util = process._linkedBinding('electron_common_v8_util');
 
 const Module = require('module');
 
-const Promise: PromiseConstructor = global.Promise as any;
+const Promise: PromiseConstructor = global.Promise;
 
 const envNoAsar = process.env.ELECTRON_NO_ASAR &&
     process.type !== 'browser' &&
     process.type !== 'renderer';
 const isAsarDisabled = () => process.noAsar || envNoAsar;
 
-const internalBinding = (process as any).internalBinding;
-delete (process as any).internalBinding;
+const internalBinding = process.internalBinding!;
+delete process.internalBinding;
 
 const nextTick = (functionToCall: Function, args: any[] = []) => {
   process.nextTick(() => functionToCall(...args));

+ 1 - 1
lib/browser/api/base-window.ts

@@ -4,7 +4,7 @@ const { BaseWindow } = process._linkedBinding('electron_browser_base_window') as
 
 Object.setPrototypeOf(BaseWindow.prototype, EventEmitter.prototype);
 
-(BaseWindow.prototype as any)._init = function () {
+BaseWindow.prototype._init = function () {
   // Avoid recursive require.
   const { app } = require('electron');
 

+ 2 - 2
lib/browser/api/browser-window.ts

@@ -4,9 +4,9 @@ const { BrowserWindow } = process._linkedBinding('electron_browser_window') as {
 
 Object.setPrototypeOf(BrowserWindow.prototype, BaseWindow.prototype);
 
-(BrowserWindow.prototype as any)._init = function (this: BWT) {
+BrowserWindow.prototype._init = function (this: BWT) {
   // Call parent class's _init.
-  (BaseWindow.prototype as any)._init.call(this);
+  BaseWindow.prototype._init.call(this);
 
   // Avoid recursive require.
   const { app } = require('electron');

+ 2 - 2
lib/browser/api/screen.ts

@@ -7,11 +7,11 @@ let _screen: Electron.Screen;
 // side-effecting and calling createScreen upon import of this module, instead
 // we export a proxy which lazily calls createScreen on first access.
 export default new Proxy({}, {
-  get: (target, prop) => {
+  get: (target, prop: keyof Electron.Screen) => {
     if (_screen === undefined) {
       _screen = createScreen();
     }
-    const v = (_screen as any)[prop];
+    const v = _screen[prop];
     if (typeof v === 'function') {
       return v.bind(_screen);
     }

+ 3 - 3
lib/browser/devtools.ts

@@ -60,7 +60,7 @@ const assertChromeDevTools = function (contents: Electron.WebContents, api: stri
   }
 };
 
-ipcMainInternal.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Electron.IpcMainInvokeEvent, items: ContextMenuItem[], isEditMenu: boolean) {
+ipcMainInternal.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event, items: ContextMenuItem[], isEditMenu: boolean) {
   return new Promise(resolve => {
     assertChromeDevTools(event.sender, 'window.InspectorFrontendHost.showContextMenuAtPoint()');
 
@@ -72,7 +72,7 @@ ipcMainInternal.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Elect
   });
 });
 
-ipcMainInternal.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event: Electron.IpcMainInvokeEvent) {
+ipcMainInternal.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event) {
   assertChromeDevTools(event.sender, 'window.UI.createFileSelectorElement()');
 
   const result = await dialog.showOpenDialog({});
@@ -84,7 +84,7 @@ ipcMainInternal.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event:
   return [path, data];
 });
 
-ipcMainUtils.handleSync('ELECTRON_INSPECTOR_CONFIRM', async function (event: Electron.IpcMainInvokeEvent, message: string = '', title: string = '') {
+ipcMainUtils.handleSync('ELECTRON_INSPECTOR_CONFIRM', async function (event, message: string = '', title: string = '') {
   assertChromeDevTools(event.sender, 'window.confirm()');
 
   const options = {

+ 3 - 3
lib/browser/guest-window-manager.ts

@@ -266,8 +266,8 @@ export function internalWindowOpen (event: ElectronInternal.IpcMainInternalEvent
   }
 }
 
-const makeSafeHandler = function<T> (handler: (event: Electron.IpcMainInvokeEvent, guestContents: Electron.webContents, ...args: any[]) => T) {
-  return (event: Electron.IpcMainInvokeEvent, guestId: number, ...args: any[]) => {
+const makeSafeHandler = function<T, Event> (handler: (event: Event, guestContents: Electron.webContents, ...args: any[]) => T) {
+  return (event: Event, guestId: number, ...args: any[]) => {
     // Access webContents via electron to prevent circular require.
     const guestContents = electron.webContents.fromId(guestId);
     if (!guestContents) {
@@ -282,7 +282,7 @@ const handleMessage = function (channel: string, handler: (event: Electron.IpcMa
   ipcMainInternal.handle(channel, makeSafeHandler(handler));
 };
 
-const handleMessageSync = function (channel: string, handler: (event: Electron.IpcMainInvokeEvent, guestContents: Electron.webContents, ...args: any[]) => any) {
+const handleMessageSync = function (channel: string, handler: (event: ElectronInternal.IpcMainInternalEvent, guestContents: Electron.webContents, ...args: any[]) => any) {
   ipcMainUtils.handleSync(channel, makeSafeHandler(handler));
 };
 

+ 2 - 2
lib/browser/ipc-main-impl.ts

@@ -13,9 +13,9 @@ export class IpcMainImpl extends EventEmitter {
     }
     this._invokeHandlers.set(method, async (e, ...args) => {
       try {
-        (e as any)._reply(await Promise.resolve(fn(e, ...args)));
+        e._reply(await Promise.resolve(fn(e, ...args)));
       } catch (err) {
-        (e as any)._throw(err);
+        e._throw(err);
       }
     });
   }

+ 1 - 1
lib/browser/ipc-main-internal-utils.ts

@@ -1,6 +1,6 @@
 import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
 
-type IPCHandler = (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any
+type IPCHandler = (event: ElectronInternal.IpcMainInternalEvent, ...args: any[]) => any
 
 export const handleSync = function <T extends IPCHandler> (channel: string, handler: T) {
   ipcMainInternal.on(channel, async (event, ...args) => {

+ 5 - 5
lib/browser/navigation-controller.ts

@@ -16,7 +16,7 @@ ipcMainInternal.on('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', function (even
 });
 
 ipcMainInternal.on('ELECTRON_NAVIGATION_CONTROLLER_LENGTH', function (event) {
-  event.returnValue = (event.sender as any).length();
+  event.returnValue = event.sender.length();
 });
 
 // JavaScript implementation of Chromium's NavigationController.
@@ -39,7 +39,7 @@ export class NavigationController extends EventEmitter {
       this.currentIndex++;
       this.history.push(this.webContents._getURL());
     }
-    this.webContents.on('navigation-entry-committed' as any, (event: any, url: string, inPage: boolean, replaceEntry: boolean) => {
+    this.webContents.on('navigation-entry-committed' as any, (event: Electron.Event, url: string, inPage: boolean, replaceEntry: boolean) => {
       if (this.inPageIndex > -1 && !inPage) {
         // Navigated to a new page, clear in-page mark.
         this.inPageIndex = -1;
@@ -82,14 +82,14 @@ export class NavigationController extends EventEmitter {
       const finishListener = () => {
         resolveAndCleanup();
       };
-      const failListener = (event: any, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean) => {
+      const failListener = (event: Electron.Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean) => {
         if (isMainFrame) {
           rejectAndCleanup(errorCode, errorDescription, validatedURL);
         }
       };
 
       let navigationStarted = false;
-      const navigationListener = (event: any, url: string, isSameDocument: boolean, isMainFrame: boolean) => {
+      const navigationListener = (event: Electron.Event, url: string, isSameDocument: boolean, isMainFrame: boolean) => {
         if (isMainFrame) {
           if (navigationStarted && !isSameDocument) {
             // the webcontents has started another unrelated navigation in the
@@ -159,7 +159,7 @@ export class NavigationController extends EventEmitter {
     return this.webContents._loadURL(this.getURL(), {
       extraHeaders: 'pragma: no-cache\n',
       reloadIgnoringCache: true
-    } as any);
+    });
   }
 
   canGoBack () {

+ 3 - 4
lib/browser/remote/server.ts

@@ -20,13 +20,12 @@ const FUNCTION_PROPERTIES = [
 
 type RendererFunctionId = [string, number] // [contextId, funcId]
 type FinalizerInfo = { id: RendererFunctionId, webContents: electron.WebContents, frameId: number };
-type WeakRef<T> = { deref(): T | undefined }
 type CallIntoRenderer = (...args: any[]) => void
 
 // The remote functions in renderer processes.
 const rendererFunctionCache = new Map<string, WeakRef<CallIntoRenderer>>();
 // eslint-disable-next-line no-undef
-const finalizationRegistry = new (globalThis as any).FinalizationRegistry((fi: FinalizerInfo) => {
+const finalizationRegistry = new FinalizationRegistry((fi: FinalizerInfo) => {
   const mapKey = fi.id[0] + '~' + fi.id[1];
   const ref = rendererFunctionCache.get(mapKey);
   if (ref !== undefined && ref.deref() === undefined) {
@@ -45,7 +44,7 @@ function getCachedRendererFunction (id: RendererFunctionId): CallIntoRenderer |
 }
 function setCachedRendererFunction (id: RendererFunctionId, wc: electron.WebContents, frameId: number, value: CallIntoRenderer) {
   // eslint-disable-next-line no-undef
-  const wr = new (globalThis as any).WeakRef(value) as WeakRef<CallIntoRenderer>;
+  const wr = new WeakRef<CallIntoRenderer>(value);
   const mapKey = id[0] + '~' + id[1];
   rendererFunctionCache.set(mapKey, wr);
   finalizationRegistry.register(value, {
@@ -263,7 +262,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
         const callIntoRenderer = function (this: any, ...args: any[]) {
           let succeed = false;
           if (!sender.isDestroyed()) {
-            succeed = (sender as any)._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args));
+            succeed = sender._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args));
           }
           if (!succeed) {
             removeRemoteListenersAndLogWarning(this, callIntoRenderer);

+ 8 - 8
lib/browser/rpc-server.ts

@@ -1,5 +1,5 @@
 import { app } from 'electron/main';
-import type { IpcMainInvokeEvent, WebContents } from 'electron/main';
+import type { WebContents } from 'electron/main';
 import { clipboard, crashReporter, nativeImage } from 'electron/common';
 import * as fs from 'fs';
 import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
@@ -25,7 +25,7 @@ const logStack = function (contents: WebContents, code: string, stack: string) {
 };
 
 // Implements window.close()
-ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event: ElectronInternal.IpcMainInternalEvent) {
+ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
   const window = event.sender.getOwnerBrowserWindow();
   if (window) {
     window.close();
@@ -33,7 +33,7 @@ ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event: ElectronInt
   event.returnValue = null;
 });
 
-ipcMainInternal.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event: IpcMainInvokeEvent) {
+ipcMainInternal.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
   return event.sender.getLastWebPreferences();
 });
 
@@ -49,7 +49,7 @@ const allowedClipboardMethods = (() => {
   }
 })();
 
-ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD_SYNC', function (event: IpcMainInvokeEvent, method: string, ...args: any[]) {
+ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD_SYNC', function (event, method: string, ...args: any[]) {
   if (!allowedClipboardMethods.has(method)) {
     throw new Error(`Invalid method: ${method}`);
   }
@@ -60,7 +60,7 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD_SYNC', function (event: IpcM
 if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) {
   const desktopCapturer = require('@electron/internal/browser/desktop-capturer');
 
-  ipcMainInternal.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', async function (event: IpcMainInvokeEvent, options: Electron.SourcesOptions, stack: string) {
+  ipcMainInternal.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', async function (event, options: Electron.SourcesOptions, stack: string) {
     logStack(event.sender, 'desktopCapturer.getSources()', stack);
     const customEvent = emitCustomEvent(event.sender, 'desktop-capturer-get-sources');
 
@@ -88,7 +88,7 @@ const getPreloadScript = async function (preloadPath: string) {
   return { preloadPath, preloadSrc, preloadError };
 };
 
-ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event: IpcMainInvokeEvent) {
+ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
   const preloadPaths = event.sender._getPreloadPaths();
   const webPreferences = event.sender.getLastWebPreferences() || {};
 
@@ -109,7 +109,7 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event:
   };
 });
 
-ipcMainInternal.on('ELECTRON_BROWSER_PRELOAD_ERROR', function (event: ElectronInternal.IpcMainInternalEvent, preloadPath: string, error: Error) {
+ipcMainInternal.on('ELECTRON_BROWSER_PRELOAD_ERROR', function (event, preloadPath: string, error: Error) {
   event.sender.emit('preload-error', event, preloadPath, error);
 });
 
@@ -125,7 +125,7 @@ ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_UPLOAD_TO_SERVER', () => {
   return crashReporter.getUploadToServer();
 });
 
-ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_SET_UPLOAD_TO_SERVER', (event: IpcMainInvokeEvent, uploadToServer: boolean) => {
+ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_SET_UPLOAD_TO_SERVER', (event, uploadToServer: boolean) => {
   return crashReporter.setUploadToServer(uploadToServer);
 });
 

+ 3 - 3
lib/common/api/deprecate.ts

@@ -43,7 +43,7 @@ const deprecate: ElectronInternal.DeprecationUtil = {
     return function (this: any) {
       warn();
       fn.apply(this, arguments);
-    };
+    } as unknown as typeof fn;
   },
 
   // change the name of a function
@@ -52,7 +52,7 @@ const deprecate: ElectronInternal.DeprecationUtil = {
     return function (this: any) {
       warn();
       return fn.apply(this, arguments);
-    };
+    } as unknown as typeof fn;
   },
 
   moveAPI<T extends Function> (fn: T, oldUsage: string, newUsage: string): T {
@@ -60,7 +60,7 @@ const deprecate: ElectronInternal.DeprecationUtil = {
     return function (this: any) {
       warn();
       return fn.apply(this, arguments);
-    } as any;
+    } as unknown as typeof fn;
   },
 
   // change the name of an event

+ 1 - 1
lib/common/type-utils.ts

@@ -34,7 +34,7 @@ const objectMap = function (source: Object, mapper: (value: any) => any) {
   return Object.fromEntries(targetEntries);
 };
 
-function serializeNativeImage (image: any) {
+function serializeNativeImage (image: Electron.NativeImage) {
   const representations = [];
   const scaleFactors = image.getScaleFactors();
 

+ 1 - 1
lib/renderer/inspector.ts

@@ -19,7 +19,7 @@ function completeURL (project: string, path: string) {
 }
 
 // The DOM implementation expects (message?: string) => boolean
-(window.confirm as any) = function (message: string, title: string) {
+window.confirm = function (message?: string, title?: string) {
   return ipcRendererUtils.invokeSync('ELECTRON_INSPECTOR_CONFIRM', message, title) as boolean;
 };
 

+ 1 - 1
lib/renderer/web-view/web-view-impl.ts

@@ -262,7 +262,7 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
 
   for (const property of properties) {
     Object.defineProperty(WebViewElement.prototype, property, {
-      get: createPropertyGetter(property) as any,
+      get: createPropertyGetter(property),
       set: createPropertySetter(property)
     });
   }

+ 2 - 2
lib/renderer/window-setup.ts

@@ -255,13 +255,13 @@ export const windowSetup = (
   if (!usesNativeWindowOpen) {
     // TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch
     // Make the browser window or guest view emit "new-window" event.
-    (window as any).open = function (url?: string, frameName?: string, features?: string) {
+    window.open = function (url?: string, frameName?: string, features?: string) {
       if (url != null && url !== '') {
         url = resolveURL(url, location.href);
       }
       const guestId = ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, toString(frameName), toString(features));
       if (guestId != null) {
-        return getOrCreateProxy(guestId);
+        return getOrCreateProxy(guestId) as any as WindowProxy;
       } else {
         return null;
       }

+ 1 - 2
spec-main/api-deprecate-spec.ts

@@ -124,8 +124,7 @@ describe('deprecate', () => {
     deprecate.setHandler(m => { msg = m; });
 
     function oldFn () { return 'hello'; }
-    function newFn () { return 'goodbye'; }
-    const deprecatedFn = deprecate.renameFunction(oldFn, newFn);
+    const deprecatedFn = deprecate.renameFunction(oldFn, 'newFn');
     deprecatedFn();
 
     expect(msg).to.be.a('string');

+ 111 - 5
typings/internal-ambient.d.ts

@@ -92,6 +92,11 @@ declare namespace NodeJS {
     initAsarSupport(require: NodeJS.Require): void;
   }
 
+  interface PowerMonitorBinding extends Electron.PowerMonitor {
+    createPowerMonitor(): PowerMonitorBinding;
+    setListeningForShutdown(listening: boolean): void;
+  }
+
   type DataPipe = {
     write: (buf: Uint8Array) => Promise<void>;
     done: () => void;
@@ -138,16 +143,51 @@ declare namespace NodeJS {
   }
 
   interface Process {
+    internalBinding?(name: string): any;
     _linkedBinding(name: string): any;
-    _linkedBinding(name: 'electron_renderer_ipc'): { ipc: IpcRendererBinding };
-    _linkedBinding(name: 'electron_common_v8_util'): V8UtilBinding;
-    _linkedBinding(name: 'electron_common_features'): FeaturesBinding;
-    _linkedBinding(name: 'electron_browser_app'): { app: Electron.App, App: Function };
+    _linkedBinding(name: 'electron_common_asar'): AsarBinding;
+    _linkedBinding(name: 'electron_common_clipboard'): Electron.Clipboard;
     _linkedBinding(name: 'electron_common_command_line'): Electron.CommandLine;
     _linkedBinding(name: 'electron_common_environment'): EnvironmentBinding;
+    _linkedBinding(name: 'electron_common_features'): FeaturesBinding;
+    _linkedBinding(name: 'electron_common_native_image'): { nativeImage: typeof Electron.NativeImage };
+    _linkedBinding(name: 'electron_common_native_theme'): { nativeTheme: Electron.NativeTheme };
+    _linkedBinding(name: 'electron_common_notification'): {
+      isSupported(): boolean;
+      Notification: typeof Electron.Notification;
+    }
+    _linkedBinding(name: 'electron_common_screen'): { createScreen(): Electron.Screen };
+    _linkedBinding(name: 'electron_common_shell'): Electron.Shell;
+    _linkedBinding(name: 'electron_common_v8_util'): V8UtilBinding;
+    _linkedBinding(name: 'electron_browser_app'): { app: Electron.App, App: Function };
+    _linkedBinding(name: 'electron_browser_auto_updater'): { autoUpdater: Electron.AutoUpdater };
+    _linkedBinding(name: 'electron_browser_browser_view'): { BrowserView: typeof Electron.BrowserView };
+    _linkedBinding(name: 'electron_browser_crash_reporter'): Omit<Electron.CrashReporter, 'start'> & {
+      start(submitUrl: string,
+        uploadToServer: boolean,
+        ignoreSystemCrashHandler: boolean,
+        rateLimit: boolean,
+        compress: boolean,
+        globalExtra: Record<string, string>,
+        extra: Record<string, string>,
+        isNodeProcess: boolean): void;
+    };
     _linkedBinding(name: 'electron_browser_desktop_capturer'): {
       createDesktopCapturer(): ElectronInternal.DesktopCapturer;
     };
+    _linkedBinding(name: 'electron_browser_event'): {
+      createWithSender(sender: Electron.WebContents): Electron.Event;
+      createEmpty(): Electron.Event;
+    };
+    _linkedBinding(name: 'electron_browser_event_emitter'): {
+      setEventEmitterPrototype(prototype: Object): void;
+    };
+    _linkedBinding(name: 'electron_browser_global_shortcut'): { globalShortcut: Electron.GlobalShortcut };
+    _linkedBinding(name: 'electron_browser_image_view'): { ImageView: any };
+    _linkedBinding(name: 'electron_browser_in_app_purchase'): { inAppPurchase: Electron.InAppPurchase };
+    _linkedBinding(name: 'electron_browser_message_port'): {
+      createPair(): { port1: Electron.MessagePortMain, port2: Electron.MessagePortMain };
+    };
     _linkedBinding(name: 'electron_browser_net'): {
       isValidHeaderName: (headerName: string) => boolean;
       isValidHeaderValue: (headerValue: string) => boolean;
@@ -155,7 +195,15 @@ declare namespace NodeJS {
       net: any;
       createURLLoader(options: CreateURLLoaderOptions): URLLoader;
     };
-    _linkedBinding(name: 'electron_common_asar'): AsarBinding;
+    _linkedBinding(name: 'electron_browser_power_monitor'): PowerMonitorBinding;
+    _linkedBinding(name: 'electron_browser_power_save_blocker'): { powerSaveBlocker: Electron.PowerSaveBlocker };
+    _linkedBinding(name: 'electron_browser_session'): typeof Electron.Session;
+    _linkedBinding(name: 'electron_browser_system_preferences'): { systemPreferences: Electron.SystemPreferences };
+    _linkedBinding(name: 'electron_browser_tray'): { Tray: Electron.Tray };
+    _linkedBinding(name: 'electron_browser_view'): { View: Electron.View };
+    _linkedBinding(name: 'electron_browser_web_contents_view'): { WebContentsView: typeof Electron.WebContentsView };
+    _linkedBinding(name: 'electron_renderer_crash_reporter'): Electron.CrashReporter;
+    _linkedBinding(name: 'electron_renderer_ipc'): { ipc: IpcRendererBinding };
     log: NodeJS.WriteStream['write'];
     activateUvLoop(): void;
 
@@ -259,3 +307,61 @@ interface ResizeObserverEntry {
    */
   readonly contentRect: DOMRectReadOnly;
 }
+
+// https://github.com/microsoft/TypeScript/pull/38232
+
+interface WeakRef<T extends object> {
+  readonly [Symbol.toStringTag]: "WeakRef";
+
+  /**
+   * Returns the WeakRef instance's target object, or undefined if the target object has been
+   * reclaimed.
+   */
+  deref(): T | undefined;
+}
+
+interface WeakRefConstructor {
+  readonly prototype: WeakRef<any>;
+
+  /**
+   * Creates a WeakRef instance for the given target object.
+   * @param target The target object for the WeakRef instance.
+   */
+  new<T extends object>(target?: T): WeakRef<T>;
+}
+
+declare var WeakRef: WeakRefConstructor;
+
+interface FinalizationRegistry {
+  readonly [Symbol.toStringTag]: "FinalizationRegistry";
+
+  /**
+   * Registers an object with the registry.
+   * @param target The target object to register.
+   * @param heldValue The value to pass to the finalizer for this object. This cannot be the
+   * target object.
+   * @param unregisterToken The token to pass to the unregister method to unregister the target
+   * object. If provided (and not undefined), this must be an object. If not provided, the target
+   * cannot be unregistered.
+   */
+  register(target: object, heldValue: any, unregisterToken?: object): void;
+
+  /**
+   * Unregisters an object from the registry.
+   * @param unregisterToken The token that was used as the unregisterToken argument when calling
+   * register to register the target object.
+   */
+  unregister(unregisterToken: object): void;
+}
+
+interface FinalizationRegistryConstructor {
+  readonly prototype: FinalizationRegistry;
+
+  /**
+   * Creates a finalization registry with an associated cleanup callback
+   * @param cleanupCallback The callback to call after an object in the registry has been reclaimed.
+   */
+  new(cleanupCallback: (heldValue: any) => void): FinalizationRegistry;
+}
+
+declare var FinalizationRegistry: FinalizationRegistryConstructor;

+ 17 - 4
typings/internal-electron.d.ts

@@ -21,7 +21,12 @@ declare namespace Electron {
 
   type TouchBarItemType = NonNullable<Electron.TouchBarConstructorOptions['items']>[0];
 
+  interface BaseWindow {
+    _init(): void;
+  }
+
   interface BrowserWindow {
+    _init(): void;
     _touchBar: Electron.TouchBar | null;
     _setTouchBarItems: (items: TouchBarItemType[]) => void;
     _setEscapeTouchBarItem: (item: TouchBarItemType | {}) => void;
@@ -47,7 +52,7 @@ declare namespace Electron {
 
   interface WebContents {
     _getURL(): string;
-    _loadURL(url: string, options: Electron.LoadURLOptions): void;
+    _loadURL(url: string, options: ElectronInternal.LoadURLOptions): void;
     _stop(): void;
     _goBack(): void;
     _goForward(): void;
@@ -61,7 +66,7 @@ declare namespace Electron {
     browserWindowOptions: BrowserWindowConstructorOptions;
     _send(internal: boolean, sendToAll: boolean, channel: string, args: any): boolean;
     _sendToFrame(internal: boolean, sendToAll: boolean, frameId: number, channel: string, args: any): boolean;
-    _sendToFrameInternal(frameId: number, channel: string, args: any): boolean;
+    _sendToFrameInternal(frameId: number, channel: string, ...args: any[]): boolean;
     _postMessage(channel: string, message: any, transfer?: any[]): void;
     _sendInternal(channel: string, ...args: any[]): void;
     _sendInternalToAll(channel: string, ...args: any[]): void;
@@ -123,6 +128,10 @@ declare namespace Electron {
     acceleratorWorksWhenHidden?: boolean;
   }
 
+  interface IpcMainInvokeEvent {
+    _reply(value: any): void;
+    _throw(error: Error): void;
+  }
 
   const deprecate: ElectronInternal.DeprecationUtil;
 
@@ -177,8 +186,8 @@ declare namespace ElectronInternal {
     getHandler(): DeprecationHandler | null;
     warn(oldName: string, newName: string): void;
     log(message: string): void;
-    removeFunction(fn: Function, removedName: string): Function;
-    renameFunction(fn: Function, newName: string | Function): Function;
+    removeFunction<T extends Function>(fn: T, removedName: string): T;
+    renameFunction<T extends Function>(fn: T, newName: string): T;
     event(emitter: NodeJS.EventEmitter, oldName: string, newName: string): void;
     removeProperty<T, K extends (keyof T & string)>(object: T, propertyName: K, onlyForValues?: any[]): T;
     renameProperty<T, K extends (keyof T & string)>(object: T, oldName: string, newName: K): T;
@@ -222,6 +231,10 @@ declare namespace ElectronInternal {
     once(channel: string, listener: (event: IpcMainInternalEvent, ...args: any[]) => void): this;
   }
 
+  interface LoadURLOptions extends Electron.LoadURLOptions {
+    reloadIgnoringCache?: boolean;
+  }
+
   type ModuleLoader = () => any;
 
   interface ModuleEntry {