declare module '@ember/template-compiler/lib/template' {
  import { type TemplateOnlyComponent } from '@ember/component/template-only';
  type ComponentClass = abstract new (...args: any[]) => object;
  /**
   * All possible options passed to `template()` may specify a `moduleName`.
   */
  export interface BaseTemplateOptions {
    moduleName?: string;
    /**
     * Whether the template should be treated as a strict-mode template. Defaults
     * to `true`.
     */
    strictMode?: boolean;
  }
  /**
   * When using `template` in a class, you call it in a `static` block and pass
   * the class as the `component` option.
   *
   * ```ts
   * class MyComponent extends Component {
   *   static {
   *     template('{{this.greeting}}, {{@place}}!',
   *       { component: this },
   *       // explicit or implicit option goes here
   *     );
   *   }
   * }
   * ```
   *
   * For the full explicit form, see {@linkcode ExplicitClassOptions}. For the
   * full implicit form, see {@linkcode ImplicitClassOptions}.
   */
  export interface BaseClassTemplateOptions<C extends ComponentClass> extends BaseTemplateOptions {
    component: C;
  }
  /**
   * When using `template` outside of a class (i.e. a "template-only component"), you can pass
   * a `scope` option that explicitly provides the lexical scope for the template.
   *
   * This is called the "explicit form".
   *
   * ```ts
   * const greeting = 'Hello';
   * const HelloWorld = template('{{greeting}} World!', { scope: () => ({ greeting }) });
   * ```
   */
  export interface ExplicitTemplateOnlyOptions extends BaseTemplateOptions {
    scope(): Record<string, unknown>;
  }
  /**
   * When using `template` *inside* a class (see
   * {@linkcode BaseClassTemplateOptions}), you can pass a `scope` option that
   * explicitly provides the lexical scope for the template, just like a template-only
   * component (see {@linkcode ExplicitTemplateOnlyOptions}).
   *
   * ```ts
   * class MyComponent extends Component {
   *   static {
   *     template('{{this.greeting}}, {{@place}}!',
   *       { component: this },
   *       // explicit or implicit option goes here
   *     );
   *   }
   * }
   * ```
   *
   * ## The Scope Function's `instance` Parameter
   *
   * However, the explicit `scope` function in a *class* also takes an `instance` option
   * that provides access to the component's instance.
   *
   * Once it's supported in Handlebars, this will make it possible to represent private
   * fields when using the explicit form.
   *
   * ```ts
   * class MyComponent extends Component {
   *   static {
   *     template('{{this.#greeting}}, {{@place}}!',
   *       { component: this },
   *       scope: (instance) => ({ '#greeting': instance.#greeting }),
   *     );
   *   }
   * }
   * ```
   */
  export interface ExplicitClassOptions<C extends ComponentClass>
    extends BaseClassTemplateOptions<C> {
    scope(instance?: InstanceType<C>): Record<string, unknown>;
  }
  /**
   * The *implicit* form of the `template` function takes an `eval` option that
   * allows the runtime compiler to evaluate local template variables without
   * needing to maintain an explicit list of the local variables used in the
   * template scope.
   *
   * The eval options *must* be passed in the following form:
   *
   * ```ts
   * {
   *   eval() { return eval(arguments[0]) }
   * }
   * ```
   *
   * ## Requirements of the `eval` Option
   *
   * **The syntactic form presented above is the only form you should use when
   * passing an `eval` option.**
   *
   * This is _required_ if you want your code to be compatible with the
   * compile-time implementation of `@ember/template-compiler`. While the runtime
   * compiler offers a tiny bit of additional wiggle room, you still need to follow
   * very strict rules.
   *
   * We don't recommend trying to memorize the rules. Instead, we recommend using
   * the snippet presented above and supported by the compile-time implementation.
   *
   * ### The Technical Requirements of the `eval` Option
   *
   * The `eval` function is passed a single parameter that is a JavaScript
   * identifier. This will be extended in the future to support private fields.
   *
   * Since keywords in JavaScript are contextual (e.g. `await` and `yield`), the
   * parameter might be a keyword. The `@ember/template-compiler/runtime` expects
   * the function to throw a `SyntaxError` if the identifier name is not valid in
   * the current scope. (The direct `eval` function takes care of this out of the
   * box.)
   *
   * Requirements:
   *
   * 1. The `eval` method must receive its parameter as `arguments[0]`, which
   *    ensures that the variable name passed to `eval()` is not shadowed by the
   *    function's parameter name.
   * 2. The `eval` option must be a function or concise method, and not an arrow.
   *    This is because arrows do not have their own `arguments`, which breaks
   *    (1).
   * 3. The `eval` method must call "*direct* `eval`", and not an alias of `eval`.
   *    Direct `eval` evaluates the code in the scope it was called from, while
   *    aliased versions of `eval` (including `new Function`) evaluate the code in
   *    the global scope.
   * 4. The `eval` method must return the result of calling "direct `eval`".
   *
   * The easiest way to achieve these requirements is to use the exact syntax
   * presented above. This is *also* the only way to be compatible
   *
   * ## Rationale
   *
   * This is useful for two reasons:
   *
   * 1. This form is a useful _intermediate_ form for the compile-time toolchain.
   *    It allows the content-tag preprocessor to convert the `<template>` syntax
   *    into valid JavaScript without needing to involve full-fledged lexical
   *    analysis.
   * 2. This form is a convenient form for manual prototyping when using the
   *    runtime compiler directly. While it requires some extra typing relative to
   *    `<template>`, it's a mechanical 1:1 transformation of the syntax.
   *
   * In practice, implementations that use a runtime compiler (for example, a
   * playground running completely in the browser) should probably use the
   * `content-tag` preprocessor to convert the template into the implicit form,
   * and then rely on `@ember/template-compiler/runtime` to evaluate the template.
   */
  export interface ImplicitEvalOption {
    eval(): unknown;
  }
  /**
   * When using `template` outside of a class (i.e. a "template-only component"), you can pass
   * an `eval` option that _implicitly_ provides the lexical scope for the template.
   *
   * This is called the "implicit form".
   *
   * ```ts
   * const greeting = 'Hello';
   * const HelloWorld = template('{{greeting}} World!', {
   *   eval() { return arguments[0] }
   * });
   * ```
   *
   * For more details on the requirements of the `eval` option, see {@linkcode ImplicitEvalOption}.
   */
  export type ImplicitTemplateOnlyOptions = BaseTemplateOptions & ImplicitEvalOption;
  /**
   * When using `template` inside of a class, you can pass an `eval` option that
   * _implicitly_ provides the lexical scope for the template, just as you can
   * with a {@linkcode ImplicitTemplateOnlyOptions | template-only component}.
   *
   * This is called the "implicit form".
   *
   * ```ts
   * class MyComponent extends Component {
   *   static {
   *     template('{{this.greeting}}, {{@place}}!',
   *       { component: this },
   *       eval() { return arguments[0] }
   *     );
   *   }
   * }
   * ```
   *
   * ## Note  on Private Fields
   *
   * The current implementation of `@ember/template-compiler` does not support
   * private fields, but once the Handlebars parser adds support for private field
   * syntax and it's implemented in the Glimmer compiler, the implicit form should
   * be able to support them.
   */
  export type ImplicitClassOptions<C extends ComponentClass> = BaseClassTemplateOptions<C> &
    ImplicitEvalOption;
  export function template(
    templateString: string,
    options?: ExplicitTemplateOnlyOptions | ImplicitTemplateOnlyOptions
  ): TemplateOnlyComponent;
  export function template<C extends ComponentClass>(
    templateString: string,
    options: ExplicitClassOptions<C> | ImplicitClassOptions<C> | BaseClassTemplateOptions<C>
  ): C;
  export {};
}
