// @flow

declare module '@swc/core' {
  /**
   * Flowtype definitions for types
   * Generated by Flowgen from a Typescript Definition
   * Flowgen v1.21.0
   */

  // see https://gist.github.com/thecotne/6e5969f4aaf8f253985ed36b30ac9fe0
  declare type $FlowGen$If<X: boolean, Then, Else = empty> = $Call<
    ((true, Then, Else) => Then) & ((false, Then, Else) => Else),
    X,
    Then,
    Else,
  >;

  declare type $FlowGen$Assignable<A, B> = $Call<
    ((...r: [B]) => true) & ((...r: [A]) => false),
    A,
  >;

  declare export type Plugin = {|
    (module: Program): Program,
  |};
  declare export type ParseOptions = {|
    ...ParserConfig,
    ...{|
      comments?: boolean,
      script?: boolean,

      /**
       * Defaults to es3.
       */
      target?: JscTarget,
    |},
  |};
  declare export type TerserEcmaVersion = 5 | 2015 | 2016 | string | number;
  declare export type JsMinifyOptions = {|
    compress?: TerserCompressOptions | boolean,
    format?: {|
      ...JsFormatOptions /*...ToSnakeCaseProperties<JsFormatOptions>*/,
    |},
    mangle?: TerserMangleOptions | boolean,
    ecma?: TerserEcmaVersion,
    keep_classnames?: boolean,
    keep_fnames?: boolean,
    module?: boolean,
    safari10?: boolean,
    toplevel?: boolean,
    sourceMap?: boolean,
    outputPath?: string,
    inlineSourcesContent?: boolean,
  |};

  /**
   * @example ToSnakeCase<'indentLevel'> == 'indent_level'
   */
  // declare type ToSnakeCase<T: string> = $FlowGen$If<$FlowGen$Assignable<T,undefined: /* NO PRINT IMPLEMENTED: TemplateLiteralType */ any>,undefined: /* NO PRINT IMPLEMENTED: TemplateLiteralType */ any,T>;
  /**
   * @example ToSnakeCaseProperties<{indentLevel: 3}> == {indent_level: 3}
   */
  // declare type ToSnakeCaseProperties<T> = $ObjMapi<T, <K>(K) => $ElementType<T, K>>;
  /**
   * These properties are mostly not implemented yet,
   * but it exists to support passing terser config to swc minify
   * without modification.
   */
  declare export type JsFormatOptions = {|
    /**
     * Currently noop.
     * @default false
     * @alias ascii_only
     */
    asciiOnly?: boolean,

    /**
     * Currently noop.
     * @default false
     */
    beautify?: boolean,

    /**
     * Currently noop.
     * @default false
     */
    braces?: boolean,

    /**
     * - `false`: removes all comments
     * - `'some'`: preserves some comments
     * - `'all'`: preserves all comments
     * @default false
     */
    comments?: false | 'some' | 'all',

    /**
     * Currently noop.
     * @default 5
     */
    ecma?: TerserEcmaVersion,

    /**
     * Currently noop.
     * @alias indent_level
     */
    indentLevel?: number,

    /**
     * Currently noop.
     * @alias indent_start
     */
    indentStart?: number,

    /**
     * Currently noop.
     * @alias inline_script
     */
    inlineScript?: number,

    /**
     * Currently noop.
     * @alias keep_numbers
     */
    keepNumbers?: number,

    /**
     * Currently noop.
     * @alias keep_quoted_props
     */
    keepQuotedProps?: boolean,

    /**
     * Currently noop.
     * @alias max_line_len
     */
    maxLineLen?: number | false,

    /**
     * Currently noop.
     */
    preamble?: string,

    /**
     * Currently noop.
     * @alias quote_keys
     */
    quoteKeys?: boolean,

    /**
     * Currently noop.
     * @alias quote_style
     */
    quoteStyle?: boolean,

    /**
     * Currently noop.
     * @alias preserve_annotations
     */
    preserveAnnotations?: boolean,

    /**
     * Currently noop.
     */
    safari10?: boolean,

    /**
     * Currently noop.
     */
    semicolons?: boolean,

    /**
     * Currently noop.
     */
    shebang?: boolean,

    /**
     * Currently noop.
     */
    webkit?: boolean,

    /**
     * Currently noop.
     * @alias wrap_iife
     */
    wrapIife?: boolean,

    /**
     * Currently noop.
     * @alias wrap_func_args
     */
    wrapFuncArgs?: boolean,
  |};
  declare export type TerserCompressOptions = {|
    arguments?: boolean,
    arrows?: boolean,
    booleans?: boolean,
    booleans_as_integers?: boolean,
    collapse_vars?: boolean,
    comparisons?: boolean,
    computed_props?: boolean,
    conditionals?: boolean,
    dead_code?: boolean,
    defaults?: boolean,
    directives?: boolean,
    drop_console?: boolean,
    drop_debugger?: boolean,
    ecma?: TerserEcmaVersion,
    evaluate?: boolean,
    expression?: boolean,
    global_defs?: any,
    hoist_funs?: boolean,
    hoist_props?: boolean,
    hoist_vars?: boolean,
    ie8?: boolean,
    if_return?: boolean,
    inline?: 0 | 1 | 2 | 3,
    join_vars?: boolean,
    keep_classnames?: boolean,
    keep_fargs?: boolean,
    keep_fnames?: boolean,
    keep_infinity?: boolean,
    loops?: boolean,
    negate_iife?: boolean,
    passes?: number,
    properties?: boolean,
    pure_getters?: any,
    pure_funcs?: string[],
    reduce_funcs?: boolean,
    reduce_vars?: boolean,
    sequences?: any,
    side_effects?: boolean,
    switches?: boolean,
    top_retain?: any,
    toplevel?: any,
    typeofs?: boolean,
    unsafe?: boolean,
    unsafe_passes?: boolean,
    unsafe_arrows?: boolean,
    unsafe_comps?: boolean,
    unsafe_function?: boolean,
    unsafe_math?: boolean,
    unsafe_symbols?: boolean,
    unsafe_methods?: boolean,
    unsafe_proto?: boolean,
    unsafe_regexp?: boolean,
    unsafe_undefined?: boolean,
    unused?: boolean,
    const_to_let?: boolean,
    module?: boolean,
  |};
  declare export type TerserMangleOptions = {|
    props?: TerserManglePropertiesOptions,
    toplevel?: boolean,
    keep_classnames?: boolean,
    keep_fnames?: boolean,
    keep_private_props?: boolean,
    ie8?: boolean,
    safari10?: boolean,
    reserved?: string[],
  |};
  declare export type TerserManglePropertiesOptions = {||};

  /**
   * Programmatic options.
   */
  declare export type Options = {|
    ...$Exact<Config>,

    /**
     * If true, a file is parsed as a script instead of module.
     */
    script?: boolean,

    /**
     * The working directory that all paths in the programmatic
     * options will be resolved relative to.
     *
     * Defaults to `process.cwd()`.
     */
    cwd?: string,
    caller?: CallerOptions,

    /**
     * The filename associated with the code currently being compiled,
     * if there is one. The filename is optional, but not all of Swc's
     * functionality is available when the filename is unknown, because a
     * subset of options rely on the filename for their functionality.
     *
     * The three primary cases users could run into are:
     *
     * - The filename is exposed to plugins. Some plugins may require the
     * presence of the filename.
     * - Options like "test", "exclude", and "ignore" require the filename
     * for string/RegExp matching.
     * - .swcrc files are loaded relative to the file being compiled.
     * If this option is omitted, Swc will behave as if swcrc: false has been set.
     */
    filename?: string,

    /**
     * The initial path that will be processed based on the "rootMode" to
     * determine the conceptual root folder for the current Swc project.
     * This is used in two primary cases:
     *
     * - The base directory when checking for the default "configFile" value
     * - The default value for "swcrcRoots".
     *
     * Defaults to `opts.cwd`
     */
    root?: string,

    /**
     * This option, combined with the "root" value, defines how Swc chooses
     * its project root. The different modes define different ways that Swc
     * can process the "root" value to get the final project root.
     *
     * "root" - Passes the "root" value through as unchanged.
     * "upward" - Walks upward from the "root" directory, looking for a directory
     * containing a swc.config.js file, and throws an error if a swc.config.js
     * is not found.
     * "upward-optional" - Walk upward from the "root" directory, looking for
     * a directory containing a swc.config.js file, and falls back to "root"
     *  if a swc.config.js is not found.
     *
     *
     * "root" is the default mode because it avoids the risk that Swc
     * will accidentally load a swc.config.js that is entirely outside
     * of the current project folder. If you use "upward-optional",
     * be aware that it will walk up the directory structure all the
     * way to the filesystem root, and it is always possible that someone
     * will have a forgotten swc.config.js in their home directory,
     * which could cause unexpected errors in your builds.
     *
     *
     * Users with monorepo project structures that run builds/tests on a
     * per-package basis may well want to use "upward" since monorepos
     * often have a swc.config.js in the project root. Running Swc
     * in a monorepo subdirectory without "upward", will cause Swc
     * to skip loading any swc.config.js files in the project root,
     * which can lead to unexpected errors and compilation failure.
     */
    rootMode?: 'root' | 'upward' | 'upward-optional',

    /**
     * The current active environment used during configuration loading.
     * This value is used as the key when resolving "env" configs,
     * and is also available inside configuration functions, plugins,
     * and presets, via the api.env() function.
     *
     * Defaults to `process.env.SWC_ENV || process.env.NODE_ENV || "development"`
     */
    envName?: string,

    /**
     * Defaults to searching for a default `.swcrc` file, but can
     * be passed the path of any JS or JSON5 config file.
     *
     *
     * NOTE: This option does not affect loading of .swcrc files,
     * so while it may be tempting to do configFile: "./foo/.swcrc",
     * it is not recommended. If the given .swcrc is loaded via the
     * standard file-relative logic, you'll end up loading the same
     * config file twice, merging it with itself. If you are linking
     * a specific config file, it is recommended to stick with a
     * naming scheme that is independent of the "swcrc" name.
     *
     * Defaults to `path.resolve(opts.root, ".swcrc")`
     */
    configFile?: string | boolean,

    /**
     * true will enable searching for configuration files relative to the "filename" provided to Swc.
     *
     * A swcrc value passed in the programmatic options will override one set within a configuration file.
     *
     * Note: .swcrc files are only loaded if the current "filename" is inside of
     *  a package that matches one of the "swcrcRoots" packages.
     *
     *
     * Defaults to true as long as the filename option has been specified
     */
    swcrc?: boolean,

    /**
     * By default, Babel will only search for .babelrc files within the "root" package
     *  because otherwise Babel cannot know if a given .babelrc is meant to be loaded,
     *  or if it's "plugins" and "presets" have even been installed, since the file
     *  being compiled could be inside node_modules, or have been symlinked into the project.
     *
     *
     * This option allows users to provide a list of other packages that should be
     * considered "root" packages when considering whether to load .babelrc files.
     *
     *
     * For example, a monorepo setup that wishes to allow individual packages
     * to have their own configs might want to do
     *
     *
     *
     * Defaults to `opts.root`
     */
    swcrcRoots?: boolean | MatchPattern | MatchPattern[],

    /**
     * `true` will attempt to load an input sourcemap from the file itself, if it
     * contains a //# sourceMappingURL=... comment. If no map is found, or the
     * map fails to load and parse, it will be silently discarded.
     *
     *  If an object is provided, it will be treated as the source map object itself.
     *
     * Defaults to `true`.
     */
    inputSourceMap?: boolean | string,

    /**
     * The name to use for the file inside the source map object.
     *
     * Defaults to `path.basename(opts.filenameRelative)` when available, or `"unknown"`.
     */
    sourceFileName?: string,

    /**
     * The sourceRoot fields to set in the generated source map, if one is desired.
     */
    sourceRoot?: string,
    plugin?: Plugin,
    isModule?: boolean | 'unknown',

    /**
     * Destination path. Note that this value is used only to fix source path
     * of source map files and swc does not write output to this path.
     */
    outputPath?: string,
  |};
  declare type BundleInput = BundleOptions | BundleOptions[];
  declare export function compileBundleOptions(
    config: BundleInput | string | void,
  ): Promise<BundleInput>;

  /**
   * Usage: In `spack.config.js` / `spack.config.ts`, you can utilize type annotations (to get autocompletions) like
   *
   * ```ts
   * import { config } from '@swc/core/spack';
   *
   * export default config({
   *      name: 'web',
   * });
   * ```
   */
  declare export function config(c: BundleInput): BundleInput;
  declare export type BundleOptions = {|
    ...$Exact<SpackConfig>,

    workingDir?: string,
  |};

  /**
   * `spack.config,js`
   */
  declare export type SpackConfig = {|
    /**
     * @default process.env.NODE_ENV
     */
    mode?: Mode,
    target?: Target,
    entry: EntryConfig,
    output: OutputConfig,
    module: ModuleConfig,
    options?: Options,

    /**
     * Modules to exclude from bundle.
     */
    externalModules?: string[],
  |};
  declare export type OutputConfig = {|
    name: string,
    path: string,
  |};
  declare export type Mode = 'production' | 'development' | 'none';
  declare export type Target = 'browser' | 'node';
  declare export type EntryConfig =
    | string
    | string[]
    | {
        [name: string]: string,
      };

  declare export type CallerOptions = {|
    name: string,
    [key: string]: any,
  |};
  declare export type Swcrc = Config | Config[];
  /**
   * .swcrc
   */
  declare export type Config = {|
    /**
     * Note: The type is string because it follows rust's regex syntax.
     */
    test?: string | string[],

    /**
     * Note: The type is string because it follows rust's regex syntax.
     */
    exclude?: string | string[],
    env?: EnvConfig,
    jsc?: JscConfig,
    module?: ModuleConfig,
    minify?: boolean,

    /**
     * - true to generate a sourcemap for the code and include it in the result object.
     * - "inline" to generate a sourcemap and append it as a data URL to the end of the code, but not include it in the result object.
     *
     * `swc-cli` overloads some of these to also affect how maps are written to disk:
     *
     * - true will write the map to a .map file on disk
     * - "inline" will write the file directly, so it will have a data: containing the map
     * - Note: These options are bit weird, so it may make the most sense to just use true
     *  and handle the rest in your own code, depending on your use case.
     */
    sourceMaps?: boolean | 'inline',
    inlineSourcesContent?: boolean,
  |};

  /**
   * Configuration ported from babel-preset-env
   */
  declare export type EnvConfig = {|
    mode?: 'usage' | 'entry',
    debug?: boolean,
    dynamicImport?: boolean,
    loose?: boolean,
    skip?: string[],
    include?: string[],
    exclude?: string[],

    /**
     * The version of the used core js.
     */
    coreJs?: string,
    targets?: any,
    path?: string,
    shippedProposals?: boolean,

    /**
     * Enable all transforms
     */
    forceAllTransforms?: boolean,
  |};
  declare export type JscConfig = {|
    loose?: boolean,

    /**
     * Defaults to EsParserConfig
     */
    parser?: ParserConfig,
    transform?: TransformConfig,

    /**
     * Use `@swc/helpers` instead of inline helpers.
     */
    externalHelpers?: boolean,

    /**
     * Defaults to `es3` (which enabled **all** pass).
     */
    target?: JscTarget,

    /**
     * Keep class names.
     */
    keepClassNames?: boolean,
    experimental?: {|
      optimizeHygiene?: boolean,
      keepImportAssertions?: boolean,

      /**
       * Specify the location where SWC stores its intermediate cache files.
       * Currently only transform plugin uses this. If not specified, SWC will
       * create `.swc` directories.
       */
      cacheRoot?: string,

      /**
       * List of custom transform plugins written in WebAssembly.
       * First parameter of tuple indicates the name of the plugin - it can be either
       * a name of the npm package can be resolved, or absolute path to .wasm binary.
       *
       * Second parameter of tuple is JSON based configuration for the plugin.
       */
      plugins?: Array<[string, {[key: string]: any}]>,
    |},
    baseUrl?: string,
    paths?: {
      [from: string]: string[],
    },
    minify?: JsMinifyOptions,
    preserveAllComments?: boolean,
  |};
  declare export type JscTarget =
    | 'es3'
    | 'es5'
    | 'es2015'
    | 'es2016'
    | 'es2017'
    | 'es2018'
    | 'es2019'
    | 'es2020'
    | 'es2021'
    | 'es2022'
    | 'esnext';
  declare export type ParserConfig = TsParserConfig | EsParserConfig;
  declare export type TsParserConfig = {|
    syntax: 'typescript',

    /**
     * Defaults to `false`.
     */
    tsx?: boolean,

    /**
     * Defaults to `false`.
     */
    decorators?: boolean,

    /**
     * Defaults to `false`
     */
    dynamicImport?: boolean,
  |};
  declare export type EsParserConfig = {|
    syntax: 'ecmascript',

    /**
     * Defaults to false.
     */
    jsx?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    numericSeparator?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    classPrivateProperty?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    privateMethod?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    classProperty?: boolean,

    /**
     * Defaults to `false`
     */
    functionBind?: boolean,

    /**
     * Defaults to `false`
     */
    decorators?: boolean,

    /**
     * Defaults to `false`
     */
    decoratorsBeforeExport?: boolean,

    /**
     * Defaults to `false`
     */
    exportDefaultFrom?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    exportNamespaceFrom?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    dynamicImport?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    nullishCoalescing?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    optionalChaining?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    importMeta?: boolean,

    /**
     * @deprecated Always true because it's in ecmascript spec.
     */
    topLevelAwait?: boolean,

    /**
     * Defaults to `false`
     */
    importAssertions?: boolean,
  |};

  /**
   * Options for transform.
   */
  declare export type TransformConfig = {|
    /**
     * Effective only if `syntax` supports ƒ.
     */
    react?: ReactConfig,
    constModules?: ConstModulesConfig,

    /**
     * Defaults to null, which skips optimizer pass.
     */
    optimizer?: OptimizerConfig,

    /**
     * https://swc.rs/docs/configuring-swc.html#jsctransformlegacydecorator
     */
    legacyDecorator?: boolean,

    /**
     * https://swc.rs/docs/configuring-swc.html#jsctransformdecoratormetadata
     */
    decoratorMetadata?: boolean,
    treatConstEnumAsEnum?: boolean,
    useDefineForClassFields?: boolean,
  |};
  declare export type ReactConfig = {|
    /**
     * Replace the function used when compiling JSX expressions.
     *
     * Defaults to `React.createElement`.
     */
    pragma?: string,

    /**
     * Replace the component used when compiling JSX fragments.
     *
     * Defaults to `React.Fragment`
     */
    pragmaFrag?: string,

    /**
     * Toggles whether or not to throw an error if a XML namespaced tag name is used. For example:
     * `<f:image />`
     *
     * Though the JSX spec allows this, it is disabled by default since React's
     * JSX does not currently have support for it.
     */
    throwIfNamespace?: boolean,

    /**
     * Toggles plugins that aid in development, such as @swc/plugin-transform-react-jsx-self
     * and @swc/plugin-transform-react-jsx-source.
     *
     * Defaults to `false`,
     */
    development?: boolean,

    /**
     * Use `Object.assign()` instead of `_extends`. Defaults to false.
     */
    useBuiltins?: boolean,

    /**
     * Enable fast refresh feature for React app
     */
    refresh?: boolean,

    /**
     * jsx runtime
     */
    runtime?: 'automatic' | 'classic',

    /**
     * Declares the module specifier to be used for importing the `jsx` and `jsxs` factory functions when using `runtime` 'automatic'
     */
    importSource?: string,
  |};

  /**
   * - `import { DEBUG } from '@ember/env-flags';`
   * - `import { FEATURE_A, FEATURE_B } from '@ember/features';`
   *
   * See: https://github.com/swc-project/swc/issues/18#issuecomment-466272558
   */
  declare export type ConstModulesConfig = {|
    globals?: {
      [module: string]: {
        [name: string]: string,
      },
    },
  |};
  declare export type OptimizerConfig = {|
    simplify?: boolean,
    globals?: GlobalPassOption,
    jsonify?: {|
      minCost: number,
    |},
  |};

  /**
   * Options for inline-global pass.
   */
  declare export type GlobalPassOption = {|
    /**
     * Global variables that should be inlined with passed value.
     *
     * e.g. `{ __DEBUG__: true }`
     */
    vars?: {[key: string]: string},

    /**
     * Names of environment variables that should be inlined with the value of corresponding env during build.
     *
     * Defaults to `["NODE_ENV", "SWC_ENV"]`
     */
    envs?: string[],

    /**
     * Replaces typeof calls for passed variables with corresponding value
     *
     * e.g. `{ window: 'object' }`
     */
    typeofs?: {[key: string]: string},
  |};
  declare export type ModuleConfig =
    | Es6Config
    | CommonJsConfig
    | UmdConfig
    | AmdConfig
    | NodeNextConfig
    | SystemjsConfig;
  declare export type BaseModuleConfig = {|
    /**
     * By default, when using exports with babel a non-enumerable `__esModule`
     * property is exported. In some cases this property is used to determine
     * if the import is the default export or if it contains the default export.
     *
     * In order to prevent the __esModule property from being exported, you
     *  can set the strict option to true.
     *
     * Defaults to `false`.
     */
    strict?: boolean,

    /**
     * Emits 'use strict' directive.
     *
     * Defaults to `true`.
     */
    strictMode?: boolean,

    /**
     * Changes Babel's compiled import statements to be lazily evaluated when their imported bindings are used for the first time.
     *
     * This can improve initial load time of your module because evaluating dependencies up
     *  front is sometimes entirely un-necessary. This is especially the case when implementing
     *  a library module.
     *
     *
     * The value of `lazy` has a few possible effects:
     *
     *  - `false` - No lazy initialization of any imported module.
     *  - `true` - Do not lazy-initialize local `./foo` imports, but lazy-init `foo` dependencies.
     *
     * Local paths are much more likely to have circular dependencies, which may break if loaded lazily,
     * so they are not lazy by default, whereas dependencies between independent modules are rarely cyclical.
     *
     *  - `Array<string>` - Lazy-initialize all imports with source matching one of the given strings.
     *
     * -----
     *
     * The two cases where imports can never be lazy are:
     *
     *  - `import "foo";`
     *
     * Side-effect imports are automatically non-lazy since their very existence means
     *  that there is no binding to later kick off initialization.
     *
     *  - `export * from "foo"`
     *
     * Re-exporting all names requires up-front execution because otherwise there is no
     * way to know what names need to be exported.
     *
     * Defaults to `false`.
     */
    lazy?: boolean | string[],

    /**
     * @deprecated Use the `importInterop` option instead.
     *
     * By default, when using exports with swc a non-enumerable __esModule property is exported.
     * This property is then used to determine if the import is the default export or if
     * it contains the default export.
     *
     * In cases where the auto-unwrapping of default is not needed, you can set the noInterop option
     * to true to avoid the usage of the interopRequireDefault helper (shown in inline form above).
     *
     * Defaults to `false`.
     */
    noInterop?: boolean,

    /**
     * Defaults to `swc`.
     *
     * CommonJS modules and ECMAScript modules are not fully compatible.
     * However, compilers, bundlers and JavaScript runtimes developed different strategies
     * to make them work together as well as possible.
     *
     * - `swc` (alias: `babel`)
     *
     * When using exports with `swc` a non-enumerable `__esModule` property is exported
     * This property is then used to determine if the import is the default export
     * or if it contains the default export.
     *
     * ```javascript
     * import foo from "foo";
     * import { bar } from "bar";
     * foo;
     * bar;
     *
     * // Is compiled to ...
     *
     * "use strict";
     *
     * function _interopRequireDefault(obj) {
     *   return obj && obj.__esModule ? obj : { default: obj };
     * }
     *
     * var _foo = _interopRequireDefault(require("foo"));
     * var _bar = require("bar");
     *
     * _foo.default;
     * _bar.bar;
     * ```
     *
     * When this import interop is used, if both the imported and the importer module are compiled
     * with swc they behave as if none of them was compiled.
     *
     * This is the default behavior.
     *
     * - `node`
     *
     * When importing CommonJS files (either directly written in CommonJS, or generated with a compiler)
     * Node.js always binds the `default` export to the value of `module.exports`.
     *
     * ```javascript
     * import foo from "foo";
     * import { bar } from "bar";
     * foo;
     * bar;
     *
     * // Is compiled to ...
     *
     * "use strict";
     *
     * var _foo = require("foo");
     * var _bar = require("bar");
     *
     * _foo;
     * _bar.bar;
     * ```
     * This is not exactly the same as what Node.js does since swc allows accessing any property of `module.exports`
     * as a named export, while Node.js only allows importing statically analyzable properties of `module.exports`.
     * However, any import working in Node.js will also work when compiled with swc using `importInterop: "node"`.
     *
     * - `none`
     *
     * If you know that the imported file has been transformed with a compiler that stores the `default` export on
     * `exports.default` (such as swc or Babel), you can safely omit the `_interopRequireDefault` helper.
     *
     * ```javascript
     * import foo from "foo";
     * import { bar } from "bar";
     * foo;
     * bar;
     *
     * // Is compiled to ...
     *
     * "use strict";
     *
     * var _foo = require("foo");
     * var _bar = require("bar");
     *
     * _foo.default;
     * _bar.bar;
     * ```
     */
    importInterop?: 'swc' | 'babel' | 'node' | 'none',

    /**
     * If set to true, dynamic imports will be preserved.
     */
    ignoreDynamic?: boolean,
    allowTopLevelThis?: boolean,
    preserveImportMeta?: boolean,
  |};
  declare export type Es6Config = {|
    ...$Exact<BaseModuleConfig>,

    type: 'es6',
  |};
  declare export type NodeNextConfig = {|
    ...$Exact<BaseModuleConfig>,

    type: 'nodenext',
  |};
  declare export type CommonJsConfig = {|
    ...$Exact<BaseModuleConfig>,

    type: 'commonjs',
  |};
  declare export type UmdConfig = {|
    ...$Exact<BaseModuleConfig>,

    type: 'umd',
    globals?: {
      [key: string]: string,
    },
  |};
  declare export type AmdConfig = {|
    ...$Exact<BaseModuleConfig>,

    type: 'amd',
    moduleId?: string,
  |};
  declare export type SystemjsConfig = {|
    type: 'systemjs',
    allowTopLevelThis?: boolean,
  |};
  declare export type Output = {|
    /**
     * Transformed code
     */
    code: string,

    /**
     * Sourcemap (**not** base64 encoded)
     */
    map?: string,
  |};
  declare export type MatchPattern = {||};

  /**
   * Version of the swc binding.
   */
  declare export var version: string;
  declare export function plugins(ps: Plugin[]): Plugin;
  declare export class Compiler {
    minify(src: string, opts?: JsMinifyOptions): Promise<Output>;
    minifySync(src: string, opts?: JsMinifyOptions): Output;
    parse(
      src: string,
      options: {|
        ...ParseOptions,
        ...{|
          isModule: false,
        |},
      |},
    ): Promise<Script>;
    parse(
      src: string,
      options?: ParseOptions,
      filename?: string,
    ): Promise<Module>;
    parseSync(
      src: string,
      options: {|
        ...ParseOptions,
        ...{|
          isModule: false,
        |},
      |},
    ): Script;
    parseSync(src: string, options?: ParseOptions, filename?: string): Module;
    parseFile(
      path: string,
      options: {|
        ...ParseOptions,
        ...{|
          isModule: false,
        |},
      |},
    ): Promise<Script>;
    parseFile(path: string, options?: ParseOptions): Promise<Module>;
    parseFileSync(
      path: string,
      options: {|
        ...ParseOptions,
        ...{|
          isModule: false,
        |},
      |},
    ): Script;
    parseFileSync(path: string, options?: ParseOptions): Module;

    /**
     * Note: this method should be invoked on the compiler instance used
     *  for `parse()` / `parseSync()`.
     */
    print(m: Program, options?: Options): Promise<Output>;

    /**
     * Note: this method should be invoked on the compiler instance used
     *  for `parse()` / `parseSync()`.
     */
    printSync(m: Program, options?: Options): Output;
    transform(src: string | Program, options?: Options): Promise<Output>;
    transformSync(src: string | Program, options?: Options): Output;
    transformFile(path: string, options?: Options): Promise<Output>;
    transformFileSync(path: string, options?: Options): Output;
    bundle(options?: BundleInput | string): Promise<{
      [name: string]: Output,
    }>;
  }
  declare export function parse(
    src: string,
    options: {|
      ...ParseOptions,
      ...{|
        isModule: false,
      |},
    |},
  ): Promise<Script>;
  declare export function parse(
    src: string,
    options?: ParseOptions,
  ): Promise<Module>;
  declare export function parseSync(
    src: string,
    options: {|
      ...ParseOptions,
      ...{|
        isModule: false,
      |},
    |},
  ): Script;
  declare export function parseSync(
    src: string,
    options?: ParseOptions,
  ): Module;
  declare export function parseFile(
    path: string,
    options: {|
      ...ParseOptions,
      ...{|
        isModule: false,
      |},
    |},
  ): Promise<Script>;
  declare export function parseFile(
    path: string,
    options?: ParseOptions,
  ): Promise<Module>;
  declare export function parseFileSync(
    path: string,
    options: {|
      ...ParseOptions,
      ...{|
        isModule: false,
      |},
    |},
  ): Script;
  declare export function parseFileSync(
    path: string,
    options?: ParseOptions,
  ): Module;
  declare export function print(m: Program, options?: Options): Promise<Output>;
  declare export function printSync(m: Program, options?: Options): Output;
  declare export function transform(
    src: string | Program,
    options?: Options,
  ): Promise<Output>;
  declare export function transformSync(
    src: string | Program,
    options?: Options,
  ): Output;
  declare export function transformFile(
    path: string,
    options?: Options,
  ): Promise<Output>;
  declare export function transformFileSync(
    path: string,
    options?: Options,
  ): Output;
  declare export function bundle(options?: BundleInput | string): Promise<{
    [name: string]: Output,
  }>;
  declare export function minify(
    src: string,
    opts?: JsMinifyOptions,
  ): Promise<Output>;
  declare export function minifySync(
    src: string,
    opts?: JsMinifyOptions,
  ): Output;

  /**
   * Configure custom trace configuration runs for a process lifecycle.
   * Currently only chromium's trace event format is supported.
   * (https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview)
   *
   * This should be called before calling any binding interfaces exported in `@swc/core`, such as
   * `transform*`, or `parse*` or anything. To avoid breaking changes, each binding fn internally
   * sets default trace subscriber if not set.
   *
   * Unlike other configuration, this does not belong to individual api surface using swcrc
   * or api's parameters (`transform(..., {trace})`). This is due to current tracing subscriber
   * can be configured only once for the global scope. Calling `registerGlobalTraceConfig` multiple
   * time won't cause error, subsequent calls will be ignored.
   *
   * As name implies currently this is experimental interface may change over time without semver
   * major breaking changes. Please provide feedbacks,
   * or bug report at https://github.com/swc-project/swc/discussions.
   */
  declare export function __experimental_registerGlobalTraceConfig(traceConfig: {|
    type: 'traceEvent',
    fileName?: string,
  |}): void;

  /**
   * @ignore Returns current binary's metadata to determine which binary is actually loaded.
   *
   * This is undocumented interface, does not guarantee stability across `@swc/core`'s semver
   * as internal representation may change anytime. Use it with caution.
   */
  declare export function getBinaryMetadata(): {|
    target: string | void,
  |};
  declare export var DEFAULT_EXTENSIONS: $ReadOnlyArray<string>;

  // AST related
  declare export type Span = {|
    start: number,
    end: number,
    ctxt: number,
  |};
  declare export type Node = {|
    type: string,
  |};
  declare export type HasSpan = {|
    span: Span,
  |};
  declare export type HasDecorator = {|
    decorators?: Decorator[],
  |};
  declare export type Klass = {|
    ...$Exact<HasSpan>,
    ...$Exact<HasDecorator>,

    body: ClassMember[],
    superClass?: Expression,
    isAbstract: boolean,
    typeParams?: TsTypeParameterDeclaration,
    superTypeParams?: TsTypeParameterInstantiation,
    implements: TsExpressionWithTypeArguments[],
  |};
  declare export type ClassMember =
    | Constructor
    | ClassMethod
    | PrivateMethod
    | ClassProperty
    | PrivateProperty
    | TsIndexSignature
    | EmptyStatement
    | StaticBlock;
  declare export type ClassPropertyBase = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,
    ...$Exact<HasDecorator>,

    value?: Expression,
    typeAnnotation?: TsTypeAnnotation,
    isStatic: boolean,
    accessibility?: Accessibility,
    isOptional: boolean,
    isOverride: boolean,
    readonly: boolean,
    definite: boolean,
  |};
  declare export type ClassProperty = {|
    ...$Exact<ClassPropertyBase>,

    type: 'ClassProperty',
    key: PropertyName,
    isAbstract: boolean,
    declare: boolean,
  |};
  declare export type PrivateProperty = {|
    ...$Exact<ClassPropertyBase>,

    type: 'PrivateProperty',
    key: PrivateName,
  |};
  declare export type Param = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,
    ...$Exact<HasDecorator>,

    type: 'Parameter',
    pat: Pattern,
  |};
  declare export type Constructor = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'Constructor',
    key: PropertyName,
    params: (TsParameterProperty | Param)[],
    body?: BlockStatement,
    accessibility?: Accessibility,
    isOptional: boolean,
  |};
  declare export type ClassMethodBase = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    function: Fn,
    kind: MethodKind,
    isStatic: boolean,
    accessibility?: Accessibility,
    isAbstract: boolean,
    isOptional: boolean,
    isOverride: boolean,
  |};
  declare export type ClassMethod = {|
    ...$Exact<ClassMethodBase>,

    type: 'ClassMethod',
    key: PropertyName,
  |};
  declare export type PrivateMethod = {|
    ...$Exact<ClassMethodBase>,

    type: 'PrivateMethod',
    key: PrivateName,
  |};
  declare export type StaticBlock = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'StaticBlock',
    body: BlockStatement,
  |};
  declare export type Decorator = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'Decorator',
    expression: Expression,
  |};
  declare export type MethodKind = 'method' | 'getter' | 'setter';
  declare export type Declaration =
    | ClassDeclaration
    | FunctionDeclaration
    | VariableDeclaration
    | TsInterfaceDeclaration
    | TsTypeAliasDeclaration
    | TsEnumDeclaration
    | TsModuleDeclaration;
  declare export type FunctionDeclaration = {|
    ...$Exact<Fn>,

    type: 'FunctionDeclaration',
    identifier: Identifier,
    declare: boolean,
  |};
  declare export type ClassDeclaration = {|
    ...$Exact<Klass>,
    ...$Exact<Node>,

    type: 'ClassDeclaration',
    identifier: Identifier,
    declare: boolean,
  |};
  declare export type VariableDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'VariableDeclaration',
    kind: VariableDeclarationKind,
    declare: boolean,
    declarations: VariableDeclarator[],
  |};
  declare export type VariableDeclarationKind = 'var' | 'let' | 'const';
  declare export type VariableDeclarator = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'VariableDeclarator',
    id: Pattern,
    init?: Expression,
    definite: boolean,
  |};
  declare export type Expression =
    | ThisExpression
    | ArrayExpression
    | ObjectExpression
    | FunctionExpression
    | UnaryExpression
    | UpdateExpression
    | BinaryExpression
    | AssignmentExpression
    | MemberExpression
    | SuperPropExpression
    | ConditionalExpression
    | CallExpression
    | NewExpression
    | SequenceExpression
    | Identifier
    | Literal
    | TemplateLiteral
    | TaggedTemplateExpression
    | ArrowFunctionExpression
    | ClassExpression
    | YieldExpression
    | MetaProperty
    | AwaitExpression
    | ParenthesisExpression
    | JSXMemberExpression
    | JSXNamespacedName
    | JSXEmptyExpression
    | JSXElement
    | JSXFragment
    | TsTypeAssertion
    | TsConstAssertion
    | TsNonNullExpression
    | TsAsExpression
    | TsInstantiation
    | PrivateName
    | OptionalChainingExpression
    | Invalid;
  declare type ExpressionBase = {|...$Exact<Node>, ...$Exact<HasSpan>|};
  declare export type Identifier = {|
    ...$Exact<ExpressionBase>,

    type: 'Identifier',
    value: string,
    optional: boolean,
  |};
  declare export type OptionalChainingExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'OptionalChainingExpression',
    questionDotToken: Span,

    /**
     * Call expression or member expression.
     */
    base: MemberExpression | OptionalChainingCall,
  |};
  declare export type OptionalChainingCall = {|
    ...$Exact<ExpressionBase>,

    type: 'CallExpression',
    callee: Expression,
    arguments: ExprOrSpread[],
    typeArguments?: TsTypeParameterInstantiation,
  |};
  declare export type ThisExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'ThisExpression',
  |};
  declare export type ArrayExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'ArrayExpression',
    elements: (ExprOrSpread | void)[],
  |};
  declare export type ExprOrSpread = {|
    spread?: Span,
    expression: Expression,
  |};
  declare export type ObjectExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'ObjectExpression',
    properties: (SpreadElement | Property)[],
  |};
  declare export type Argument = {|
    spread?: Span,
    expression: Expression,
  |};
  declare export type SpreadElement = {|
    ...$Exact<Node>,

    type: 'SpreadElement',
    spread: Span,
    arguments: Expression,
  |};
  declare export type UnaryExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'UnaryExpression',
    operator: UnaryOperator,
    argument: Expression,
  |};
  declare export type UpdateExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'UpdateExpression',
    operator: UpdateOperator,
    prefix: boolean,
    argument: Expression,
  |};
  declare export type BinaryExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'BinaryExpression',
    operator: BinaryOperator,
    left: Expression,
    right: Expression,
  |};
  declare export type FunctionExpression = {|
    ...$Exact<Fn>,
    ...$Exact<ExpressionBase>,

    type: 'FunctionExpression',
    identifier?: Identifier,
  |};
  declare export type ClassExpression = {|
    ...$Exact<Klass>,
    ...$Exact<ExpressionBase>,

    type: 'ClassExpression',
    identifier?: Identifier,
  |};
  declare export type AssignmentExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'AssignmentExpression',
    operator: AssignmentOperator,
    left: Expression | Pattern,
    right: Expression,
  |};
  declare export type MemberExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'MemberExpression',
    object: Expression,
    property: Identifier | PrivateName | ComputedPropName,
  |};
  declare export type SuperPropExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'SuperPropExpression',
    obj: Super,
    property: Identifier | ComputedPropName,
  |};
  declare export type ConditionalExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'ConditionalExpression',
    test: Expression,
    consequent: Expression,
    alternate: Expression,
  |};
  declare export type Super = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'Super',
  |};
  declare export type Import = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'Import',
  |};
  declare export type CallExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'CallExpression',
    callee: Super | Import | Expression,
    arguments: Argument[],
    typeArguments?: TsTypeParameterInstantiation,
  |};
  declare export type NewExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'NewExpression',
    callee: Expression,
    arguments?: Argument[],
    typeArguments?: TsTypeParameterInstantiation,
  |};
  declare export type SequenceExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'SequenceExpression',
    expressions: Expression[],
  |};
  declare export type ArrowFunctionExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'ArrowFunctionExpression',
    params: Pattern[],
    body: BlockStatement | Expression,
    async: boolean,
    generator: boolean,
    typeParameters?: TsTypeParameterDeclaration,
    returnType?: TsTypeAnnotation,
  |};
  declare export type YieldExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'YieldExpression',
    argument?: Expression,
    delegate: boolean,
  |};
  declare export type MetaProperty = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'MetaProperty',
    kind: 'new.target' | 'import.meta',
  |};
  declare export type AwaitExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'AwaitExpression',
    argument: Expression,
  |};
  declare export type TemplateLiteral = {|
    ...$Exact<ExpressionBase>,

    type: 'TemplateLiteral',
    expressions: Expression[],
    quasis: TemplateElement[],
  |};
  declare export type TaggedTemplateExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'TaggedTemplateExpression',
    tag: Expression,
    typeParameters?: TsTypeParameterInstantiation,
    template: TemplateLiteral,
  |};
  declare export type TemplateElement = {|
    ...$Exact<ExpressionBase>,

    type: 'TemplateElement',
    tail: boolean,
    cooked?: string,
    raw: string,
  |};
  declare export type ParenthesisExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'ParenthesisExpression',
    expression: Expression,
  |};
  declare export type Fn = {|
    ...$Exact<HasSpan>,
    ...$Exact<HasDecorator>,

    params: Param[],
    body?: BlockStatement,
    generator: boolean,
    async: boolean,
    typeParameters?: TsTypeParameterDeclaration,
    returnType?: TsTypeAnnotation,
  |};
  declare type PatternBase = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    typeAnnotation?: TsTypeAnnotation,
  |};
  declare export type PrivateName = {|
    ...$Exact<ExpressionBase>,

    type: 'PrivateName',
    id: Identifier,
  |};
  declare export type JSXObject = JSXMemberExpression | Identifier;
  declare export type JSXMemberExpression = {|
    ...$Exact<Node>,

    type: 'JSXMemberExpression',
    object: JSXObject,
    property: Identifier,
  |};

  /**
   * XML-based namespace syntax:
   */
  declare export type JSXNamespacedName = {|
    ...$Exact<Node>,

    type: 'JSXNamespacedName',
    namespace: Identifier,
    name: Identifier,
  |};
  declare export type JSXEmptyExpression = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXEmptyExpression',
  |};
  declare export type JSXExpressionContainer = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXExpressionContainer',
    expression: JSXExpression,
  |};
  declare export type JSXExpression = JSXEmptyExpression | Expression;
  declare export type JSXSpreadChild = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXSpreadChild',
    expression: Expression,
  |};
  declare export type JSXElementName =
    | Identifier
    | JSXMemberExpression
    | JSXNamespacedName;
  declare export type JSXOpeningElement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXOpeningElement',
    name: JSXElementName,
    attributes: JSXAttributeOrSpread[],
    selfClosing: boolean,
    typeArguments?: TsTypeParameterInstantiation,
  |};
  declare export type JSXAttributeOrSpread = JSXAttribute | SpreadElement;
  declare export type JSXClosingElement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXClosingElement',
    name: JSXElementName,
  |};
  declare export type JSXAttribute = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXAttribute',
    name: JSXAttributeName,
    value?: JSXAttrValue,
  |};
  declare export type JSXAttributeName = Identifier | JSXNamespacedName;
  declare export type JSXAttrValue =
    | Literal
    | JSXExpressionContainer
    | JSXElement
    | JSXFragment;
  declare export type JSXText = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXText',
    value: string,
    raw: string,
  |};
  declare export type JSXElement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXElement',
    opening: JSXOpeningElement,
    children: JSXElementChild[],
    closing?: JSXClosingElement,
  |};
  declare export type JSXElementChild =
    | JSXText
    | JSXExpressionContainer
    | JSXSpreadChild
    | JSXElement
    | JSXFragment;
  declare export type JSXFragment = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXFragment',
    opening: JSXOpeningFragment,
    children: JSXElementChild[],
    closing: JSXClosingFragment,
  |};
  declare export type JSXOpeningFragment = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXOpeningFragment',
  |};
  declare export type JSXClosingFragment = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'JSXClosingFragment',
  |};
  declare export type Literal =
    | StringLiteral
    | BooleanLiteral
    | NullLiteral
    | NumericLiteral
    | BigIntLiteral
    | RegExpLiteral
    | JSXText;
  declare export type StringLiteral = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'StringLiteral',
    value: string,
    raw?: string,
  |};
  declare export type BooleanLiteral = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'BooleanLiteral',
    value: boolean,
  |};
  declare export type NullLiteral = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'NullLiteral',
  |};
  declare export type RegExpLiteral = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'RegExpLiteral',
    pattern: string,
    flags: string,
  |};
  declare export type NumericLiteral = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'NumericLiteral',
    value: number,
    raw?: string,
  |};

  // $FlowFixMe borrowed this from packages/core/utils/src/BitSet.js
  declare type TmpBigInt = bigint;

  declare export type BigIntLiteral = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'BigIntLiteral',
    value: TmpBigInt,
    raw?: string,
  |};
  declare export type ModuleDeclaration =
    | ImportDeclaration
    | ExportDeclaration
    | ExportNamedDeclaration
    | ExportDefaultDeclaration
    | ExportDefaultExpression
    | ExportAllDeclaration
    | TsImportEqualsDeclaration
    | TsExportAssignment
    | TsNamespaceExportDeclaration;
  declare export type ExportDefaultExpression = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportDefaultExpression',
    expression: Expression,
  |};
  declare export type ExportDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportDeclaration',
    declaration: Declaration,
  |};
  declare export type ImportDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ImportDeclaration',
    specifiers: ImportSpecifier[],
    source: StringLiteral,
    typeOnly: boolean,
    asserts?: ObjectExpression,
  |};
  declare export type ExportAllDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportAllDeclaration',
    source: StringLiteral,
    asserts?: ObjectExpression,
  |};

  /**
   * - `export { foo } from 'mod'`
   * - `export { foo as bar } from 'mod'`
   */
  declare export type ExportNamedDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportNamedDeclaration',
    specifiers: ExportSpecifier[],
    source?: StringLiteral,
    typeOnly: boolean,
    asserts?: ObjectExpression,
  |};
  declare export type ExportDefaultDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportDefaultDeclaration',
    decl: DefaultDecl,
  |};
  declare export type DefaultDecl =
    | ClassExpression
    | FunctionExpression
    | TsInterfaceDeclaration;
  declare export type ImportSpecifier =
    | NamedImportSpecifier
    | ImportDefaultSpecifier
    | ImportNamespaceSpecifier;
  /**
   * e.g. `import foo from 'mod.js'`
   */
  declare export type ImportDefaultSpecifier = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ImportDefaultSpecifier',
    local: Identifier,
  |};

  /**
   * e.g. `import * as foo from 'mod.js'`.
   */
  declare export type ImportNamespaceSpecifier = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ImportNamespaceSpecifier',
    local: Identifier,
  |};

  /**
   * e.g. - `import { foo } from 'mod.js'`
   *
   * local = foo, imported = None
   *
   * e.g. `import { foo as bar } from 'mod.js'`
   *
   * local = bar, imported = Some(foo) for
   */
  declare export type NamedImportSpecifier = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ImportSpecifier',
    local: Identifier,
    imported?: ModuleExportName,
    isTypeOnly: boolean,
  |};
  declare export type ModuleExportName = Identifier | StringLiteral;
  declare export type ExportSpecifier =
    | ExportNamespaceSpecifier
    | ExportDefaultSpecifier
    | NamedExportSpecifier;
  /**
   * `export * as foo from 'src';`
   */
  declare export type ExportNamespaceSpecifier = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportNamespaceSpecifier',
    name: ModuleExportName,
  |};
  declare export type ExportDefaultSpecifier = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportDefaultSpecifier',
    exported: Identifier,
  |};
  declare export type NamedExportSpecifier = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExportSpecifier',
    orig: ModuleExportName,

    /**
     * `Some(bar)` in `export { foo as bar }`
     */
    exported?: ModuleExportName,
    isTypeOnly: boolean,
  |};
  declare type HasInterpreter = {|
    /**
     * e.g. `/usr/bin/node` for `#!/usr/bin/node`
     */
    interpreter: string,
  |};
  declare export type Program = Module | Script;
  declare export type Module = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,
    ...$Exact<HasInterpreter>,

    type: 'Module',
    body: ModuleItem[],
  |};
  declare export type Script = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,
    ...$Exact<HasInterpreter>,

    type: 'Script',
    body: Statement[],
  |};
  declare export type ModuleItem = ModuleDeclaration | Statement;
  declare export type BinaryOperator =
    | '=='
    | '!='
    | '==='
    | '!=='
    | '<'
    | '<='
    | '>'
    | '>='
    | '<<'
    | '>>'
    | '>>>'
    | '+'
    | '-'
    | '*'
    | '/'
    | '%'
    | '|'
    | '^'
    | '&'
    | '||'
    | '&&'
    | 'in'
    | 'instanceof'
    | '**'
    | '??';
  declare export type AssignmentOperator =
    | '='
    | '+='
    | '-='
    | '*='
    | '/='
    | '%='
    | '<<='
    | '>>='
    | '>>>='
    | '|='
    | '^='
    | '&='
    | '**='
    | '&&='
    | '||='
    | '??=';
  declare export type UpdateOperator = '++' | '--';
  declare export type UnaryOperator =
    | '-'
    | '+'
    | '!'
    | '~'
    | 'typeof'
    | 'void'
    | 'delete';
  declare export type Pattern =
    | BindingIdentifier
    | ArrayPattern
    | RestElement
    | ObjectPattern
    | AssignmentPattern
    | Invalid
    | Expression;
  declare export type BindingIdentifier = {|
    ...$Exact<PatternBase>,

    type: 'Identifier',
    value: string,
    optional: boolean,
  |};
  declare export type ArrayPattern = {|
    ...$Exact<PatternBase>,

    type: 'ArrayPattern',
    elements: (Pattern | void)[],
    optional: boolean,
  |};
  declare export type ObjectPattern = {|
    ...$Exact<PatternBase>,

    type: 'ObjectPattern',
    properties: ObjectPatternProperty[],
    optional: boolean,
  |};
  declare export type AssignmentPattern = {|
    ...$Exact<PatternBase>,

    type: 'AssignmentPattern',
    left: Pattern,
    right: Expression,
  |};
  declare export type RestElement = {|
    ...$Exact<PatternBase>,

    type: 'RestElement',
    rest: Span,
    argument: Pattern,
  |};
  declare export type ObjectPatternProperty =
    | KeyValuePatternProperty
    | AssignmentPatternProperty
    | RestElement;
  /**
   * `{key: value}`
   */
  declare export type KeyValuePatternProperty = {|
    ...$Exact<Node>,

    type: 'KeyValuePatternProperty',
    key: PropertyName,
    value: Pattern,
  |};

  /**
   * `{key}` or `{key = value}`
   */
  declare export type AssignmentPatternProperty = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'AssignmentPatternProperty',
    key: Identifier,
    value?: Expression,
  |};

  /**
   * Identifier is `a` in `{ a, }`
   */
  declare export type Property =
    | Identifier
    | KeyValueProperty
    | AssignmentProperty
    | GetterProperty
    | SetterProperty
    | MethodProperty;
  declare type PropBase = {|
    ...$Exact<Node>,

    key: PropertyName,
  |};
  declare export type KeyValueProperty = {|
    ...$Exact<PropBase>,

    type: 'KeyValueProperty',
    value: Expression,
  |};
  declare export type AssignmentProperty = {|
    ...$Exact<Node>,

    type: 'AssignmentProperty',
    key: Identifier,
    value: Expression,
  |};
  declare export type GetterProperty = {|
    ...$Exact<PropBase>,
    ...$Exact<HasSpan>,

    type: 'GetterProperty',
    typeAnnotation?: TsTypeAnnotation,
    body?: BlockStatement,
  |};
  declare export type SetterProperty = {|
    ...$Exact<PropBase>,
    ...$Exact<HasSpan>,

    type: 'SetterProperty',
    param: Pattern,
    body?: BlockStatement,
  |};
  declare export type MethodProperty = {|
    ...$Exact<PropBase>,
    ...$Exact<Fn>,

    type: 'MethodProperty',
  |};
  declare export type PropertyName =
    | Identifier
    | StringLiteral
    | NumericLiteral
    | ComputedPropName
    | BigIntLiteral;
  declare export type ComputedPropName = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'Computed',
    expression: Expression,
  |};
  declare export type BlockStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'BlockStatement',
    stmts: Statement[],
  |};
  declare export type ExpressionStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ExpressionStatement',
    expression: Expression,
  |};
  declare export type Statement =
    | BlockStatement
    | EmptyStatement
    | DebuggerStatement
    | WithStatement
    | ReturnStatement
    | LabeledStatement
    | BreakStatement
    | ContinueStatement
    | IfStatement
    | SwitchStatement
    | ThrowStatement
    | TryStatement
    | WhileStatement
    | DoWhileStatement
    | ForStatement
    | ForInStatement
    | ForOfStatement
    | Declaration
    | ExpressionStatement;
  declare export type EmptyStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'EmptyStatement',
  |};
  declare export type DebuggerStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'DebuggerStatement',
  |};
  declare export type WithStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'WithStatement',
    object: Expression,
    body: Statement,
  |};
  declare export type ReturnStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ReturnStatement',
    argument?: Expression,
  |};
  declare export type LabeledStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'LabeledStatement',
    label: Identifier,
    body: Statement,
  |};
  declare export type BreakStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'BreakStatement',
    label?: Identifier,
  |};
  declare export type ContinueStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ContinueStatement',
    label?: Identifier,
  |};
  declare export type IfStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'IfStatement',
    test: Expression,
    consequent: Statement,
    alternate?: Statement,
  |};
  declare export type SwitchStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'SwitchStatement',
    discriminant: Expression,
    cases: SwitchCase[],
  |};
  declare export type ThrowStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ThrowStatement',
    argument: Expression,
  |};
  declare export type TryStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TryStatement',
    block: BlockStatement,
    handler?: CatchClause,
    finalizer?: BlockStatement,
  |};
  declare export type WhileStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'WhileStatement',
    test: Expression,
    body: Statement,
  |};
  declare export type DoWhileStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'DoWhileStatement',
    test: Expression,
    body: Statement,
  |};
  declare export type ForStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ForStatement',
    init?: VariableDeclaration | Expression,
    test?: Expression,
    update?: Expression,
    body: Statement,
  |};
  declare export type ForInStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ForInStatement',
    left: VariableDeclaration | Pattern,
    right: Expression,
    body: Statement,
  |};
  declare export type ForOfStatement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'ForOfStatement',

    /**
     * Span of the await token.
     *
     * es2018 for-await-of statements, e.g., `for await (const x of xs) {`
     */
    await?: Span,
    left: VariableDeclaration | Pattern,
    right: Expression,
    body: Statement,
  |};
  declare export type SwitchCase = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'SwitchCase',

    /**
     * Undefined for default case
     */
    test?: Expression,
    consequent: Statement[],
  |};
  declare export type CatchClause = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'CatchClause',

    /**
     * The param is `undefined` if the catch binding is omitted. E.g., `try { foo() } catch {}`
     */
    param?: Pattern,
    body: BlockStatement,
  |};
  declare export type TsTypeAnnotation = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeAnnotation',
    typeAnnotation: TsType,
  |};
  declare export type TsTypeParameterDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeParameterDeclaration',
    parameters: TsTypeParameter[],
  |};
  declare export type TsTypeParameter = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeParameter',
    name: Identifier,
    in: boolean,
    out: boolean,
    constraint?: TsType,
    default?: TsType,
  |};
  declare export type TsTypeParameterInstantiation = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeParameterInstantiation',
    params: TsType[],
  |};
  declare export type TsParameterProperty = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,
    ...$Exact<HasDecorator>,

    type: 'TsParameterProperty',
    accessibility?: Accessibility,
    override: boolean,
    readonly: boolean,
    param: TsParameterPropertyParameter,
  |};
  declare export type TsParameterPropertyParameter =
    | BindingIdentifier
    | AssignmentPattern;
  declare export type TsQualifiedName = {|
    ...$Exact<Node>,

    type: 'TsQualifiedName',
    left: TsEntityName,
    right: Identifier,
  |};
  declare export type TsEntityName = TsQualifiedName | Identifier;
  declare export type TsTypeElement =
    | TsCallSignatureDeclaration
    | TsConstructSignatureDeclaration
    | TsPropertySignature
    | TsGetterSignature
    | TsSetterSignature
    | TsMethodSignature
    | TsIndexSignature;
  declare export type TsCallSignatureDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsCallSignatureDeclaration',
    params: TsFnParameter[],
    typeAnnotation?: TsTypeAnnotation,
    typeParams?: TsTypeParameterDeclaration,
  |};
  declare export type TsConstructSignatureDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsConstructSignatureDeclaration',
    params: TsFnParameter[],
    typeAnnotation?: TsTypeAnnotation,
    typeParams?: TsTypeParameterDeclaration,
  |};
  declare export type TsPropertySignature = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsPropertySignature',
    readonly: boolean,
    key: Expression,
    computed: boolean,
    optional: boolean,
    init?: Expression,
    params: TsFnParameter[],
    typeAnnotation?: TsTypeAnnotation,
    typeParams?: TsTypeParameterDeclaration,
  |};
  declare export type TsGetterSignature = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsGetterSignature',
    readonly: boolean,
    key: Expression,
    computed: boolean,
    optional: boolean,
    typeAnnotation?: TsTypeAnnotation,
  |};
  declare export type TsSetterSignature = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsSetterSignature',
    readonly: boolean,
    key: Expression,
    computed: boolean,
    optional: boolean,
    param: TsFnParameter,
  |};
  declare export type TsMethodSignature = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsMethodSignature',
    readonly: boolean,
    key: Expression,
    computed: boolean,
    optional: boolean,
    params: TsFnParameter[],
    typeAnn?: TsTypeAnnotation,
    typeParams?: TsTypeParameterDeclaration,
  |};
  declare export type TsIndexSignature = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsIndexSignature',
    params: TsFnParameter[],
    typeAnnotation?: TsTypeAnnotation,
    readonly: boolean,
    static: boolean,
  |};
  declare export type TsType =
    | TsKeywordType
    | TsThisType
    | TsFnOrConstructorType
    | TsTypeReference
    | TsTypeQuery
    | TsTypeLiteral
    | TsArrayType
    | TsTupleType
    | TsOptionalType
    | TsRestType
    | TsUnionOrIntersectionType
    | TsConditionalType
    | TsInferType
    | TsParenthesizedType
    | TsTypeOperator
    | TsIndexedAccessType
    | TsMappedType
    | TsLiteralType
    | TsTypePredicate
    | TsImportType;
  declare export type TsFnOrConstructorType =
    | TsFunctionType
    | TsConstructorType;
  declare export type TsKeywordType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsKeywordType',
    kind: TsKeywordTypeKind,
  |};
  declare export type TsKeywordTypeKind =
    | 'any'
    | 'unknown'
    | 'number'
    | 'object'
    | 'boolean'
    | 'bigint'
    | 'string'
    | 'symbol'
    | 'void'
    | 'undefined'
    | 'null'
    | 'never'
    | 'intrinsic';
  declare export type TsThisType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsThisType',
  |};
  declare export type TsFnParameter =
    | BindingIdentifier
    | ArrayPattern
    | RestElement
    | ObjectPattern;
  declare export type TsFunctionType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsFunctionType',
    params: TsFnParameter[],
    typeParams?: TsTypeParameterDeclaration,
    typeAnnotation: TsTypeAnnotation,
  |};
  declare export type TsConstructorType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsConstructorType',
    params: TsFnParameter[],
    typeParams?: TsTypeParameterDeclaration,
    typeAnnotation: TsTypeAnnotation,
    isAbstract: boolean,
  |};
  declare export type TsTypeReference = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeReference',
    typeName: TsEntityName,
    typeParams?: TsTypeParameterInstantiation,
  |};
  declare export type TsTypePredicate = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypePredicate',
    asserts: boolean,
    paramName: TsThisTypeOrIdent,
    typeAnnotation?: TsTypeAnnotation,
  |};
  declare export type TsThisTypeOrIdent = TsThisType | Identifier;
  declare export type TsImportType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsImportType',
    argument: StringLiteral,
    qualifier?: TsEntityName,
    typeArguments?: TsTypeParameterInstantiation,
  |};

  /**
   * `typeof` operator
   */
  declare export type TsTypeQuery = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeQuery',
    exprName: TsTypeQueryExpr,
    typeArguments?: TsTypeParameterInstantiation,
  |};
  declare export type TsTypeQueryExpr = TsEntityName | TsImportType;
  declare export type TsTypeLiteral = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeLiteral',
    members: TsTypeElement[],
  |};
  declare export type TsArrayType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsArrayType',
    elemType: TsType,
  |};
  declare export type TsTupleType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTupleType',
    elemTypes: TsTupleElement[],
  |};
  declare export type TsTupleElement = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTupleElement',
    label?: Pattern,
    ty: TsType,
  |};
  declare export type TsOptionalType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsOptionalType',
    typeAnnotation: TsType,
  |};
  declare export type TsRestType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsRestType',
    typeAnnotation: TsType,
  |};
  declare export type TsUnionOrIntersectionType =
    | TsUnionType
    | TsIntersectionType;
  declare export type TsUnionType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsUnionType',
    types: TsType[],
  |};
  declare export type TsIntersectionType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsIntersectionType',
    types: TsType[],
  |};
  declare export type TsConditionalType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsConditionalType',
    checkType: TsType,
    extendsType: TsType,
    trueType: TsType,
    falseType: TsType,
  |};
  declare export type TsInferType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsInferType',
    typeParam: TsTypeParameter,
  |};
  declare export type TsParenthesizedType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsParenthesizedType',
    typeAnnotation: TsType,
  |};
  declare export type TsTypeOperator = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeOperator',
    op: TsTypeOperatorOp,
    typeAnnotation: TsType,
  |};
  declare export type TsTypeOperatorOp = 'keyof' | 'unique' | 'readonly';
  declare export type TsIndexedAccessType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsIndexedAccessType',
    readonly: boolean,
    objectType: TsType,
    indexType: TsType,
  |};
  declare export type TruePlusMinus = true | '+' | '-';
  declare export type TsMappedType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsMappedType',
    readonly?: TruePlusMinus,
    typeParam: TsTypeParameter,
    nameType?: TsType,
    optional?: TruePlusMinus,
    typeAnnotation?: TsType,
  |};
  declare export type TsLiteralType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsLiteralType',
    literal: TsLiteral,
  |};
  declare export type TsLiteral =
    | NumericLiteral
    | StringLiteral
    | BooleanLiteral
    | BigIntLiteral
    | TsTemplateLiteralType;
  declare export type TsTemplateLiteralType = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TemplateLiteral',
    types: TsType[],
    quasis: TemplateElement[],
  |};
  declare export type TsInterfaceDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsInterfaceDeclaration',
    id: Identifier,
    declare: boolean,
    typeParams?: TsTypeParameterDeclaration,
    extends: TsExpressionWithTypeArguments[],
    body: TsInterfaceBody,
  |};
  declare export type TsInterfaceBody = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsInterfaceBody',
    body: TsTypeElement[],
  |};
  declare export type TsExpressionWithTypeArguments = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsExpressionWithTypeArguments',
    expression: Expression,
    typeArguments?: TsTypeParameterInstantiation,
  |};
  declare export type TsTypeAliasDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsTypeAliasDeclaration',
    declare: boolean,
    id: Identifier,
    typeParams?: TsTypeParameterDeclaration,
    typeAnnotation: TsType,
  |};
  declare export type TsEnumDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsEnumDeclaration',
    declare: boolean,
    isConst: boolean,
    id: Identifier,
    members: TsEnumMember[],
  |};
  declare export type TsEnumMember = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsEnumMember',
    id: TsEnumMemberId,
    init?: Expression,
  |};
  declare export type TsEnumMemberId = Identifier | StringLiteral;
  declare export type TsModuleDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsModuleDeclaration',
    declare: boolean,
    global: boolean,
    id: TsModuleName,
    body?: TsNamespaceBody,
  |};

  /**
   * `namespace A.B { }` is a namespace named `A` with another TsNamespaceDecl as its body.
   */
  declare export type TsNamespaceBody = TsModuleBlock | TsNamespaceDeclaration;
  declare export type TsModuleBlock = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsModuleBlock',
    body: ModuleItem[],
  |};
  declare export type TsNamespaceDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsNamespaceDeclaration',
    declare: boolean,
    global: boolean,
    id: Identifier,
    body: TsNamespaceBody,
  |};
  declare export type TsModuleName = Identifier | StringLiteral;
  declare export type TsImportEqualsDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsImportEqualsDeclaration',
    declare: boolean,
    isExport: boolean,
    isTypeOnly: boolean,
    id: Identifier,
    moduleRef: TsModuleReference,
  |};
  declare export type TsModuleReference =
    | TsEntityName
    | TsExternalModuleReference;
  declare export type TsExternalModuleReference = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsExternalModuleReference',
    expression: StringLiteral,
  |};
  declare export type TsExportAssignment = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsExportAssignment',
    expression: Expression,
  |};
  declare export type TsNamespaceExportDeclaration = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsNamespaceExportDeclaration',
    id: Identifier,
  |};
  declare export type TsAsExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'TsAsExpression',
    expression: Expression,
    typeAnnotation: TsType,
  |};
  declare export type TsInstantiation = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'TsInstantiation',
    expression: Expression,
    typeArguments: TsTypeParameterInstantiation,
  |};
  declare export type TsTypeAssertion = {|
    ...$Exact<ExpressionBase>,

    type: 'TsTypeAssertion',
    expression: Expression,
    typeAnnotation: TsType,
  |};
  declare export type TsConstAssertion = {|
    ...$Exact<ExpressionBase>,

    type: 'TsConstAssertion',
    expression: Expression,
  |};
  declare export type TsNonNullExpression = {|
    ...$Exact<ExpressionBase>,

    type: 'TsNonNullExpression',
    expression: Expression,
  |};
  declare export type Accessibility = 'public' | 'protected' | 'private';
  declare export type Invalid = {|
    ...$Exact<Node>,
    ...$Exact<HasSpan>,

    type: 'Invalid',
  |};
}

declare module '@swc/core/Visitor' {
  import type {
    Accessibility,
    ArrayExpression,
    ArrayPattern,
    ArrowFunctionExpression,
    Argument,
    AssignmentExpression,
    AssignmentPattern,
    AssignmentPatternProperty,
    AssignmentProperty,
    AwaitExpression,
    BigIntLiteral,
    BinaryExpression,
    BlockStatement,
    BooleanLiteral,
    BreakStatement,
    CallExpression,
    CatchClause,
    Klass,
    ClassDeclaration,
    ClassExpression,
    ClassMember,
    ClassMethod,
    ClassProperty,
    ComputedPropName,
    ConditionalExpression,
    Constructor,
    ContinueStatement,
    DebuggerStatement,
    Declaration,
    Decorator,
    DefaultDecl,
    DoWhileStatement,
    EmptyStatement,
    ExportAllDeclaration,
    ExportDeclaration,
    ExportDefaultDeclaration,
    ExportDefaultExpression,
    ExportDefaultSpecifier,
    ExportNamedDeclaration,
    ExportNamespaceSpecifier,
    ExportSpecifier,
    Expression,
    ExpressionStatement,
    Fn,
    ForInStatement,
    ForOfStatement,
    ForStatement,
    FunctionDeclaration,
    FunctionExpression,
    GetterProperty,
    Identifier,
    IfStatement,
    ImportDeclaration,
    ImportDefaultSpecifier,
    ImportNamespaceSpecifier,
    ImportSpecifier,
    JSXAttribute,
    JSXAttributeName,
    JSXAttributeOrSpread,
    JSXAttrValue,
    JSXClosingElement,
    JSXClosingFragment,
    JSXElement,
    JSXElementChild,
    JSXElementName,
    JSXEmptyExpression,
    JSXExpressionContainer,
    JSXFragment,
    JSXMemberExpression,
    JSXNamespacedName,
    JSXObject,
    JSXOpeningElement,
    JSXOpeningFragment,
    JSXSpreadChild,
    JSXText,
    KeyValuePatternProperty,
    KeyValueProperty,
    LabeledStatement,
    MemberExpression,
    MetaProperty,
    MethodProperty,
    Module,
    ModuleDeclaration,
    ModuleExportName,
    ModuleItem,
    NamedExportSpecifier,
    NamedImportSpecifier,
    NewExpression,
    NullLiteral,
    NumericLiteral,
    ObjectExpression,
    ObjectPattern,
    ObjectPatternProperty,
    OptionalChainingCall,
    OptionalChainingExpression,
    ParenthesisExpression,
    Pattern,
    PrivateMethod,
    PrivateName,
    PrivateProperty,
    Program,
    Property,
    PropertyName,
    RegExpLiteral,
    RestElement,
    ReturnStatement,
    Script,
    SequenceExpression,
    SetterProperty,
    SpreadElement,
    Statement,
    StaticBlock,
    StringLiteral,
    Super,
    SwitchCase,
    SwitchStatement,
    TaggedTemplateExpression,
    TemplateLiteral,
    ThisExpression,
    ThrowStatement,
    TryStatement,
    TsAsExpression,
    TsCallSignatureDeclaration,
    TsConstructSignatureDeclaration,
    TsEntityName,
    TsEnumDeclaration,
    TsEnumMember,
    TsEnumMemberId,
    TsExportAssignment,
    TsExpressionWithTypeArguments,
    TsExternalModuleReference,
    TsFnParameter,
    TsGetterSignature,
    TsImportEqualsDeclaration,
    TsIndexSignature,
    TsInstantiation,
    TsInterfaceBody,
    TsInterfaceDeclaration,
    TsMethodSignature,
    TsModuleBlock,
    TsModuleDeclaration,
    TsModuleName,
    TsModuleReference,
    TsNamespaceBody,
    TsNamespaceDeclaration,
    TsNamespaceExportDeclaration,
    TsNonNullExpression,
    TsParameterProperty,
    TsParameterPropertyParameter,
    TsPropertySignature,
    TsQualifiedName,
    TsSetterSignature,
    TsType,
    TsTypeAliasDeclaration,
    TsTypeAnnotation,
    TsTypeAssertion,
    TsTypeElement,
    TsTypeParameter,
    TsTypeParameterDeclaration,
    TsTypeParameterInstantiation,
    UnaryExpression,
    UpdateExpression,
    VariableDeclaration,
    VariableDeclarator,
    WhileStatement,
    WithStatement,
    YieldExpression,
    Param,
    ExprOrSpread,
    TsConstAssertion,
    Import,
    SuperPropExpression,
  } from '@swc/core';
  declare export class Visitor {
    visitProgram(n: Program): Program;
    visitModule(m: Module): Module;
    visitScript(m: Script): Script;
    visitModuleItems(items: ModuleItem[]): ModuleItem[];
    visitModuleItem(n: ModuleItem): ModuleItem;
    visitModuleDeclaration(n: ModuleDeclaration): ModuleDeclaration;
    visitTsNamespaceExportDeclaration(
      n: TsNamespaceExportDeclaration,
    ): ModuleDeclaration;
    visitTsExportAssignment(n: TsExportAssignment): TsExportAssignment;
    visitTsImportEqualsDeclaration(
      n: TsImportEqualsDeclaration,
    ): ModuleDeclaration;
    visitTsModuleReference(n: TsModuleReference): TsModuleReference;
    visitTsExternalModuleReference(
      n: TsExternalModuleReference,
    ): TsExternalModuleReference;
    visitExportAllDeclaration(n: ExportAllDeclaration): ModuleDeclaration;
    visitExportDefaultExpression(n: ExportDefaultExpression): ModuleDeclaration;
    visitExportNamedDeclaration(n: ExportNamedDeclaration): ModuleDeclaration;
    visitExportSpecifiers(nodes: ExportSpecifier[]): ExportSpecifier[];
    visitExportSpecifier(n: ExportSpecifier): ExportSpecifier;
    visitNamedExportSpecifier(n: NamedExportSpecifier): ExportSpecifier;
    visitModuleExportName(n: ModuleExportName): ModuleExportName;
    visitExportNamespaceSpecifier(n: ExportNamespaceSpecifier): ExportSpecifier;
    visitExportDefaultSpecifier(n: ExportDefaultSpecifier): ExportSpecifier;
    visitOptionalStringLiteral(n: StringLiteral | void): StringLiteral | void;
    visitExportDefaultDeclaration(
      n: ExportDefaultDeclaration,
    ): ModuleDeclaration;
    visitDefaultDeclaration(n: DefaultDecl): DefaultDecl;
    visitFunctionExpression(n: FunctionExpression): FunctionExpression;
    visitClassExpression(n: ClassExpression): ClassExpression;
    visitExportDeclaration(n: ExportDeclaration): ModuleDeclaration;
    visitArrayExpression(e: ArrayExpression): Expression;
    visitArrayElement(e: ExprOrSpread | void): ExprOrSpread | void;
    visitExprOrSpread(e: ExprOrSpread): ExprOrSpread;
    visitExprOrSpreads(nodes: ExprOrSpread[]): ExprOrSpread[];
    visitSpreadElement(e: SpreadElement): SpreadElement;
    visitOptionalExpression(e: Expression | void): Expression | void;
    visitArrowFunctionExpression(e: ArrowFunctionExpression): Expression;
    visitArrowBody(
      body: BlockStatement | Expression,
    ): BlockStatement | Expression;
    visitBlockStatement(block: BlockStatement): BlockStatement;
    visitStatements(stmts: Statement[]): Statement[];
    visitStatement(stmt: Statement): Statement;
    visitSwitchStatement(stmt: SwitchStatement): Statement;
    visitSwitchCases(cases: SwitchCase[]): SwitchCase[];
    visitSwitchCase(c: SwitchCase): SwitchCase;
    visitIfStatement(stmt: IfStatement): Statement;
    visitOptionalStatement(stmt: Statement | void): Statement | void;
    visitBreakStatement(stmt: BreakStatement): Statement;
    visitWhileStatement(stmt: WhileStatement): Statement;
    visitTryStatement(stmt: TryStatement): Statement;
    visitCatchClause(handler: CatchClause | void): CatchClause | void;
    visitThrowStatement(stmt: ThrowStatement): Statement;
    visitReturnStatement(stmt: ReturnStatement): Statement;
    visitLabeledStatement(stmt: LabeledStatement): Statement;
    visitForStatement(stmt: ForStatement): Statement;
    visitForOfStatement(stmt: ForOfStatement): Statement;
    visitForInStatement(stmt: ForInStatement): Statement;
    visitEmptyStatement(stmt: EmptyStatement): EmptyStatement;
    visitDoWhileStatement(stmt: DoWhileStatement): Statement;
    visitDebuggerStatement(stmt: DebuggerStatement): Statement;
    visitWithStatement(stmt: WithStatement): Statement;
    visitDeclaration(decl: Declaration): Declaration;
    visitVariableDeclaration(n: VariableDeclaration): VariableDeclaration;
    visitVariableDeclarators(nodes: VariableDeclarator[]): VariableDeclarator[];
    visitVariableDeclarator(n: VariableDeclarator): VariableDeclarator;
    visitTsTypeAliasDeclaration(n: TsTypeAliasDeclaration): Declaration;
    visitTsModuleDeclaration(n: TsModuleDeclaration): Declaration;
    visitTsModuleName(n: TsModuleName): TsModuleName;
    visitTsNamespaceBody(n: TsNamespaceBody): TsNamespaceBody | void;
    visitTsNamespaceDeclaration(
      n: TsNamespaceDeclaration,
    ): TsModuleBlock | TsNamespaceDeclaration;
    visitTsModuleBlock(
      n: TsModuleBlock,
    ): TsModuleBlock | TsNamespaceDeclaration;
    visitTsInterfaceDeclaration(
      n: TsInterfaceDeclaration,
    ): TsInterfaceDeclaration;
    visitTsInterfaceBody(n: TsInterfaceBody): TsInterfaceBody;
    visitTsTypeElements(nodes: TsTypeElement[]): TsTypeElement[];
    visitTsTypeElement(n: TsTypeElement): TsTypeElement;
    visitTsCallSignatureDeclaration(
      n: TsCallSignatureDeclaration,
    ): TsCallSignatureDeclaration;
    visitTsConstructSignatureDeclaration(
      n: TsConstructSignatureDeclaration,
    ): TsConstructSignatureDeclaration;
    visitTsPropertySignature(n: TsPropertySignature): TsPropertySignature;
    visitTsGetterSignature(n: TsGetterSignature): TsGetterSignature;
    visitTsSetterSignature(n: TsSetterSignature): TsSetterSignature;
    visitTsMethodSignature(n: TsMethodSignature): TsMethodSignature;
    visitTsEnumDeclaration(n: TsEnumDeclaration): Declaration;
    visitTsEnumMembers(nodes: TsEnumMember[]): TsEnumMember[];
    visitTsEnumMember(n: TsEnumMember): TsEnumMember;
    visitTsEnumMemberId(n: TsEnumMemberId): TsEnumMemberId;
    visitFunctionDeclaration(decl: FunctionDeclaration): Declaration;
    visitClassDeclaration(decl: ClassDeclaration): Declaration;
    visitClassBody(members: ClassMember[]): ClassMember[];
    visitClassMember(member: ClassMember): ClassMember;
    visitTsIndexSignature(n: TsIndexSignature): TsIndexSignature;
    visitTsFnParameters(params: TsFnParameter[]): TsFnParameter[];
    visitTsFnParameter(n: TsFnParameter): TsFnParameter;
    visitPrivateProperty(n: PrivateProperty): ClassMember;
    visitPrivateMethod(n: PrivateMethod): ClassMember;
    visitPrivateName(n: PrivateName): PrivateName;
    visitConstructor(n: Constructor): ClassMember;
    visitConstructorParameters(
      nodes: (Param | TsParameterProperty)[],
    ): (Param | TsParameterProperty)[];
    visitConstructorParameter(
      n: Param | TsParameterProperty,
    ): Param | TsParameterProperty;
    visitStaticBlock(n: StaticBlock): StaticBlock;
    visitTsParameterProperty(
      n: TsParameterProperty,
    ): TsParameterProperty | Param;
    visitTsParameterPropertyParameter(
      n: TsParameterPropertyParameter,
    ): TsParameterPropertyParameter;
    visitPropertyName(key: PropertyName): PropertyName;
    visitAccessibility(n: Accessibility | void): Accessibility | void;
    visitClassProperty(n: ClassProperty): ClassMember;
    visitClassMethod(n: ClassMethod): ClassMember;
    visitComputedPropertyKey(n: ComputedPropName): ComputedPropName;
    visitClass<T: Klass>(n: T): T;
    visitFunction<T: Fn>(n: T): T;
    visitTsExpressionsWithTypeArguments(
      nodes: TsExpressionWithTypeArguments[],
    ): TsExpressionWithTypeArguments[];
    visitTsExpressionWithTypeArguments(
      n: TsExpressionWithTypeArguments,
    ): TsExpressionWithTypeArguments;
    visitTsTypeParameterInstantiation(
      n: TsTypeParameterInstantiation | void,
    ): TsTypeParameterInstantiation | void;
    visitTsTypes(nodes: TsType[]): TsType[];
    visitTsEntityName(n: TsEntityName): TsEntityName;
    visitTsQualifiedName(n: TsQualifiedName): TsQualifiedName;
    visitDecorators(nodes: Decorator[] | void): Decorator[] | void;
    visitDecorator(n: Decorator): Decorator;
    visitExpressionStatement(stmt: ExpressionStatement): Statement;
    visitContinueStatement(stmt: ContinueStatement): Statement;
    visitExpression(n: Expression): Expression;
    visitOptionalChainingExpression(n: OptionalChainingExpression): Expression;
    visitMemberExpressionOrOptionalChainingCall(
      n: MemberExpression | OptionalChainingCall,
    ): MemberExpression | OptionalChainingCall;
    visitOptionalChainingCall(n: OptionalChainingCall): OptionalChainingCall;
    visitAssignmentExpression(n: AssignmentExpression): Expression;
    visitPatternOrExpression(n: Pattern | Expression): Pattern | Expression;
    visitYieldExpression(n: YieldExpression): Expression;
    visitUpdateExpression(n: UpdateExpression): Expression;
    visitUnaryExpression(n: UnaryExpression): Expression;
    visitTsTypeAssertion(n: TsTypeAssertion): Expression;
    visitTsConstAssertion(n: TsConstAssertion): Expression;
    visitTsInstantiation(n: TsInstantiation): TsInstantiation;
    visitTsNonNullExpression(n: TsNonNullExpression): Expression;
    visitTsAsExpression(n: TsAsExpression): Expression;
    visitThisExpression(n: ThisExpression): Expression;
    visitTemplateLiteral(n: TemplateLiteral): Expression;
    visitParameters(n: Param[]): Param[];
    visitParameter(n: Param): Param;
    visitTaggedTemplateExpression(n: TaggedTemplateExpression): Expression;
    visitSequenceExpression(n: SequenceExpression): Expression;
    visitRegExpLiteral(n: RegExpLiteral): Expression;
    visitParenthesisExpression(n: ParenthesisExpression): Expression;
    visitObjectExpression(n: ObjectExpression): Expression;
    visitObjectProperties(
      nodes: (Property | SpreadElement)[],
    ): (Property | SpreadElement)[];
    visitObjectProperty(n: Property | SpreadElement): Property | SpreadElement;
    visitProperty(n: Property): Property | SpreadElement;
    visitSetterProperty(n: SetterProperty): Property | SpreadElement;
    visitMethodProperty(n: MethodProperty): Property | SpreadElement;
    visitKeyValueProperty(n: KeyValueProperty): Property | SpreadElement;
    visitGetterProperty(n: GetterProperty): Property | SpreadElement;
    visitAssignmentProperty(n: AssignmentProperty): Property | SpreadElement;
    visitNullLiteral(n: NullLiteral): NullLiteral;
    visitNewExpression(n: NewExpression): Expression;
    visitTsTypeArguments(
      n: TsTypeParameterInstantiation | void,
    ): TsTypeParameterInstantiation | void;
    visitArguments(nodes: Argument[]): Argument[];
    visitArgument(n: Argument): Argument;
    visitMetaProperty(n: MetaProperty): Expression;
    visitMemberExpression(n: MemberExpression): MemberExpression;
    visitSuperPropExpression(n: SuperPropExpression): Expression;
    visitCallee(n: Expression | Super | Import): Expression | Super | Import;
    visitJSXText(n: JSXText): JSXText;
    visitJSXNamespacedName(n: JSXNamespacedName): JSXNamespacedName;
    visitJSXMemberExpression(n: JSXMemberExpression): JSXMemberExpression;
    visitJSXObject(n: JSXObject): JSXObject;
    visitJSXFragment(n: JSXFragment): JSXFragment;
    visitJSXClosingFragment(n: JSXClosingFragment): JSXClosingFragment;
    visitJSXElementChildren(nodes: JSXElementChild[]): JSXElementChild[];
    visitJSXElementChild(n: JSXElementChild): JSXElementChild;
    visitJSXExpressionContainer(
      n: JSXExpressionContainer,
    ): JSXExpressionContainer;
    visitJSXSpreadChild(n: JSXSpreadChild): JSXElementChild;
    visitJSXOpeningFragment(n: JSXOpeningFragment): JSXOpeningFragment;
    visitJSXEmptyExpression(n: JSXEmptyExpression): Expression;
    visitJSXElement(n: JSXElement): JSXElement;
    visitJSXClosingElement(
      n: JSXClosingElement | void,
    ): JSXClosingElement | void;
    visitJSXElementName(n: JSXElementName): JSXElementName;
    visitJSXOpeningElement(n: JSXOpeningElement): JSXOpeningElement;
    visitJSXAttributes(
      attrs: JSXAttributeOrSpread[] | void,
    ): JSXAttributeOrSpread[] | void;
    visitJSXAttributeOrSpread(n: JSXAttributeOrSpread): JSXAttributeOrSpread;
    visitJSXAttributeOrSpreads(
      nodes: JSXAttributeOrSpread[],
    ): JSXAttributeOrSpread[];
    visitJSXAttribute(n: JSXAttribute): JSXAttributeOrSpread;
    visitJSXAttributeValue(n: JSXAttrValue | void): JSXAttrValue | void;
    visitJSXAttributeName(n: JSXAttributeName): JSXAttributeName;
    visitConditionalExpression(n: ConditionalExpression): Expression;
    visitCallExpression(n: CallExpression): Expression;
    visitBooleanLiteral(n: BooleanLiteral): BooleanLiteral;
    visitBinaryExpression(n: BinaryExpression): Expression;
    visitAwaitExpression(n: AwaitExpression): Expression;
    visitTsTypeParameterDeclaration(
      n: TsTypeParameterDeclaration | void,
    ): TsTypeParameterDeclaration | void;
    visitTsTypeParameters(nodes: TsTypeParameter[]): TsTypeParameter[];
    visitTsTypeParameter(n: TsTypeParameter): TsTypeParameter;
    visitTsTypeAnnotation(a: TsTypeAnnotation | void): TsTypeAnnotation | void;
    visitTsType(n: TsType): TsType;
    visitPatterns(nodes: Pattern[]): Pattern[];
    visitImportDeclaration(n: ImportDeclaration): ImportDeclaration;
    visitImportSpecifiers(nodes: ImportSpecifier[]): ImportSpecifier[];
    visitImportSpecifier(node: ImportSpecifier): ImportSpecifier;
    visitNamedImportSpecifier(node: NamedImportSpecifier): NamedImportSpecifier;
    visitImportNamespaceSpecifier(
      node: ImportNamespaceSpecifier,
    ): ImportNamespaceSpecifier;
    visitImportDefaultSpecifier(node: ImportDefaultSpecifier): ImportSpecifier;
    visitBindingIdentifier(i: Identifier): Identifier;
    visitIdentifierReference(i: Identifier): Identifier;
    visitLabelIdentifier(label: Identifier): Identifier;
    visitIdentifier(n: Identifier): Identifier;
    visitStringLiteral(n: StringLiteral): StringLiteral;
    visitNumericLiteral(n: NumericLiteral): NumericLiteral;
    visitBigIntLiteral(n: BigIntLiteral): BigIntLiteral;
    visitPattern(n: Pattern): Pattern;
    visitRestElement(n: RestElement): RestElement;
    visitAssignmentPattern(n: AssignmentPattern): Pattern;
    visitObjectPattern(n: ObjectPattern): Pattern;
    visitObjectPatternProperties(
      nodes: ObjectPatternProperty[],
    ): ObjectPatternProperty[];
    visitObjectPatternProperty(n: ObjectPatternProperty): ObjectPatternProperty;
    visitKeyValuePatternProperty(
      n: KeyValuePatternProperty,
    ): ObjectPatternProperty;
    visitAssignmentPatternProperty(
      n: AssignmentPatternProperty,
    ): ObjectPatternProperty;
    visitArrayPattern(n: ArrayPattern): Pattern;
    visitArrayPatternElements(nodes: (Pattern | void)[]): (Pattern | void)[];
    visitArrayPatternElement(n: Pattern | void): Pattern | void;
  }
  declare export default typeof Visitor;
}
