fix(typescript-fetch): emit erasable syntax in the runtime template

Closed
MV
2mo ago
+968-198

The typescript-fetch runtime template uses TypeScript constructor parameter properties in nine places. A parameter property both declares a field and assigns it, so it is not erasable syntax — it cannot be removed by stripping types.

Two consequences for generated clients:

  • Node refuses to load the generated runtime.ts at all under type stripping: SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript parameter property is not supported in strip-only mode. Since Node 24 this is the default loader for .ts files, so a generated client cannot be run without a build step.
  • tsc --erasableSyntaxOnly (TypeScript 5.8+) rejects every one of those sites with TS1294.

Separately, FetchError declares cause, which collides with Error.cause on ES2022 and later lib targets. Consumers compiling with --noImplicitOverride get TS4115. Adding an override modifier is not an option because it breaks the lib targets that predate Error.cause (TS4113) — including the generator's own default es5/es6 output. Declaring cause on a merged interface instead satisfies both.

fixes #22400
fixes #14515

Change

runtime.mustache only. Every parameter property becomes an explicit field declaration plus an assignment in the constructor body, and FetchError.cause moves to an interface declaration. Public API, field visibility and emitted JavaScript semantics are unchanged.

export class Configuration {
    private configuration: ConfigurationParameters;

    constructor(configuration: ConfigurationParameters = {}) {
        this.configuration = configuration;
    }
}

Verification

Against the regenerated samples:

  • tsc --noEmit on builds/es6-target, builds/with-npm-version, builds/prefix-parameter-interfaces and builds/without-runtime-checks — clean.
  • The same, with --target es2022 --erasableSyntaxOnly --noImplicitOverride — clean.
  • Node 24 loads builds/default/runtime.ts directly, constructs Configuration, BaseAPI, RequiredError, FetchError, ResponseError and the four ApiResponse classes, and reads back their fields. The same script against the previous output fails with SyntaxError: TypeScript parameter property is not supported in strip-only mode.

PR checklist

cc @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @topce (2018/10) @akehir (2019/07) @petejohansonxo (2019/11) @amakhrov (2020/02) @davidgamero (2022/03) @mkusaka (2022/04) @joscha (2024/10) @dennisameling (2026/02)


Summary by cubic

Emit erasable TypeScript in the typescript-fetch runtime and fix FetchError.cause compatibility. Generated clients now run with Node 24’s strip-only loader and compile with tsc --erasableSyntaxOnly.

  • Bug Fixes
    • Replaced constructor parameter properties with explicit fields and assignments; behavior and visibility unchanged.
    • Declared FetchError.cause on a merged interface to avoid TS4115/TS4113 across lib targets.
    • Regenerated samples to use the updated runtime.