declare module "timers" {
  export const setTimeout: typeof globalThis.setTimeout;
  export const clearTimeout: typeof globalThis.clearTimeout;
  export const setInterval: typeof globalThis.setInterval;
  export const clearInterval: typeof globalThis.clearInterval;
  export const setImmediate: typeof globalThis.setImmediate;
  export const queueMicrotask: typeof globalThis.queueMicrotask;
  const _default: {
    setTimeout: typeof setTimeout;
    clearTimeout: typeof clearTimeout;
    setInterval: typeof setInterval;
    clearInterval: typeof clearInterval;
    setImmediate: typeof setImmediate;
    queueMicrotask: typeof queueMicrotask;
  };
  export default _default;

  global {
    /**
     * LLRT timers return numeric identifiers that can be passed back to
     * `clearTimeout()` or `clearInterval()` to cancel the scheduled action.
     */
    type Timer = number;

    /**
     * Schedules execution of a one-time `callback` after `delay` milliseconds.
     *
     * The `callback` will likely not be invoked in precisely `delay` milliseconds.
     * LLRT makes no guarantees about the exact timing of when callbacks will fire,
     * nor of their ordering. The callback will be called as close as possible to the
     * time specified. The precision is limited to 4ms.
     *
     * @param callback The function to call when the timer elapses.
     * @param [delay=4] The number of milliseconds to wait before calling the `callback`.
     * @return for use with {@link clearTimeout}
     */
    function setTimeout<TArgs extends any[]>(
      callback: (...args: TArgs) => void,
      ms?: number
    ): Timer;

    /**
     * Cancels a `Timeout` object created by `setTimeout()`.
     * @param timeout A `Timeout` object as returned by {@link setTimeout}.
     */
    function clearTimeout(timeout?: Timer | null): void;

    /**
     * Schedules repeated execution of `callback` every `delay` milliseconds.
     *
     * The `callback` will likely not be invoked at precisely `delay` milliseconds.
     * LLRT makes no guarantees about the exact timing of when callbacks will fire,
     * nor of their ordering. The callback will be called as close as possible to the
     * time specified. The precision is limited to 4ms.
     *
     * @param callback The function to call when the timer elapses.
     * @param [delay=4] The number of milliseconds to wait before calling the `callback`.
     * @return for use with {@link clearInterval}
     */
    function setInterval<TArgs extends any[]>(
      callback: (...args: TArgs) => void,
      ms?: number
    ): Timer;

    /**
     * Cancels a `Timeout` object created by `setInterval()`.
     * @param timeout A `Timeout` object as returned by {@link setInterval}
     */
    function clearInterval(interval?: Timer | null): void;

    /**
     * Schedules the "immediate" execution of the `callback` after I/O events'
     * callbacks.
     *
     * @param callback The function to call at the end of this turn of the Node.js `Event Loop`
     * @return for use with {@link clearTimeout} or {@link clearInterval}
     */
    function setImmediate<TArgs extends any[]>(
      callback: (...args: TArgs) => void
    ): Timer;

    function queueMicrotask(callback: () => void): void;
  }
}
