definitelytyped-firefox-webext-browser icon indicating copy to clipboard operation
definitelytyped-firefox-webext-browser copied to clipboard

Wrong "func" type in "browser.scripting" API

Open Juraj-Masiar opened this issue 2 years ago • 1 comments

Hello, First, thank you for new update!

I've checked it in all my projects and found only one issue:

declare namespace browser.scripting {
  func?: () => void | undefined;

The function type func?: () => void | undefined; should be probably func?: (...args: any) => any;. The first issue is the arguments - the function will be called with arguments based on the "args" property in the interface ScriptInjection. Second issue is the return type, function can return a value which is then used in the "InjectionResult" here:

    interface InjectionResult {
        /** The frame ID associated with the injection. */
        frameId: number;
        /** The result of the script execution. */
        result?: any;
        /**
         * The error property is set when the script execution failed. The value is typically an (Error) object with a message property, but could be any value (including primitives and undefined) if the script threw or rejected with such a value.
         */
        error?: any;
    }

In ideal world one would use generics instead of any, but I guess it's ok to keep it simple for now.

Juraj-Masiar avatar Jan 16 '23 09:01 Juraj-Masiar

Hello again :),

Now that the new Firefox ESR 115 is out, I've been looking into this. I think this types would fix the variable argument types and result type and it even has correct generics used:

declare namespace browser.scripting {

  interface ScriptInjection<T, Args extends readonly any[]> {
    /**
     * The arguments to curry into a provided function. This is only valid if the `func` parameter is specified. These arguments must be JSON-serializable.
     */
    args?: Args;
    /**
     * The path of the JS files to inject, relative to the extension's root directory. Exactly one of `files` and `func` must be specified.
     */
    files?: string[] | undefined;
    /**
     * A JavaScript function to inject. This function will be serialized, and then deserialized for injection. This means that any bound parameters and execution context will be lost. Exactly one of `files` and `func` must be specified.
     */
    func?: ((...args: Args) => T) | undefined;
    /** Details specifying the target into which to inject the script. */
    target: InjectionTarget;
    world?: ExecutionWorld | undefined;
    /**
     * Whether the injection should be triggered in the target as soon as possible (but not necessarily prior to page load).
     */
    injectImmediately?: boolean | undefined;
  }

  /** Result of a script injection. */
  interface InjectionResult<T> {
    /** The frame ID associated with the injection. */
    frameId: number;
    /** The result of the script execution. */
    result?: T;
    /**
     * The error property is set when the script execution failed. The value is typically an (Error) object with a message property, but could be any value (including primitives and undefined) if the script threw or rejected with such a value.
     */
    error?: any;
  }

  /* scripting functions */
  /**
   * Injects a script into a target context. The script will be run at `document_idle`.
   * @param injection The details of the script which to inject.
   */
  function executeScript<T, Args extends readonly any[] = []>(injection: ScriptInjection<T, Args>): Promise<InjectionResult<T>[]>;
}


Juraj-Masiar avatar Sep 28 '23 09:09 Juraj-Masiar