Skip to content

[typescript-fetch] use fileNaming-converted filenames in model imports - #24508

Open
mvhenten wants to merge 1 commit into
OpenAPITools:masterfrom
mvhenten:fix/typescript-fetch-oneof-file-naming
Open

[typescript-fetch] use fileNaming-converted filenames in model imports#24508
mvhenten wants to merge 1 commit into
OpenAPITools:masterfrom
mvhenten:fix/typescript-fetch-oneof-file-naming

Conversation

@mvhenten

@mvhenten mvhenten commented Jul 28, 2026

Copy link
Copy Markdown

Model imports in the typescript-fetch templates are emitted with the model's classname rather than its generated filename. Under the default fileNaming the two are identical, so this is invisible; with fileNaming: kebab-case or camelCase the import specifier does not match the file on disk and the generated client does not compile.

Two template sites are affected:

  1. modelOneOf.mustache — every oneOf model, with or without a discriminator.
  2. modelGeneric.mustache — the discriminator-mapped model imports.

modelOneOf.mustache now takes the non-discriminator variants from tsImports, which already carries the converted filename and is what modelGeneric.mustache uses for its own imports. Discriminator-mapped models are not present in tsImports (they are filtered out of imports in TypeScriptFetchClientCodegen.postProcessAllModels), so both templates resolve those through {{model.classFilename}}. No generator code changes.

Generated models/test-response.ts with fileNaming: kebab-case, alongside models/test-a.ts:

-import type { TestA } from './TestA';
+import type { TestA } from './test-a';

and kebab-case/models/animal.ts, alongside models/cat.ts:

-import { type Cat, CatFromJSONTyped, CatToJSON, CatToJSONTyped } from './Cat';
+import { type Cat, CatFromJSONTyped, CatToJSON, CatToJSONTyped } from './cat';

bin/configs/typescript-fetch-oneOf-kebab-case.yaml combines the existing oneOf spec with fileNaming: kebab-case. It sets npmName so the sample gets a package.json and tsconfig.json and is therefore covered by bin/ts-typecheck-all.sh. Before the fix that sample fails with 20 TS2307: Cannot find module errors; after it type-checks clean. Samples generated with the default fileNaming are byte-identical.

Context: fileNaming support was added in #18284 and covered modelGeneric's tsImports loop only; #11354 tracks TypeScript filename and import mismatches more broadly.

@leonyu

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/typescript-fetch*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Commit all changed files.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Fixes the TypeScript Fetch generator to import models using fileNaming-converted filenames, preventing TS2307 errors when fileNaming is kebab-case or camelCase. Adds a oneOf kebab-case sample to type-check this path in CI.

  • Bug Fixes
    • modelOneOf.mustache: import non-discriminator variants from tsImports via {{filename}}; import discriminator-mapped variants via {{model.classFilename}}.
    • modelGeneric.mustache: import discriminator-mapped models via {{model.classFilename}}.
    • Adds bin/configs/typescript-fetch-oneOf-kebab-case.yaml and a sample build published as @openapitools/typescript-fetch-oneof-kebab-case for CI type-checking.
    • No generator code changes; default fileNaming output remains unchanged.

Written for commit 0b8fb1c. Summary will update on new commits.

Review in cubic

modelOneOf.mustache imported oneOf variants by classname instead of by
generated filename, and modelGeneric.mustache did the same for
discriminator-mapped models. With fileNaming set to kebab-case or
camelCase the emitted specifier does not match the file on disk and the
client fails to compile.

Adds a typescript-fetch-oneOf-kebab-case sample so CI type-checks the
combination.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 48 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/client/petstore/typescript-fetch/builds/oneOf-kebab-case/src/models/test-response.ts">

<violation number="1" location="samples/client/petstore/typescript-fetch/builds/oneOf-kebab-case/src/models/test-response.ts:45">
P2: Malformed primitive responses are returned as `TestResponse`: this early guard accepts numbers and booleans even though this union only permits `string`. Handle the allowed string explicitly, then reject other primitives so runtime deserialization matches the declared union.</violation>
</file>

<file name="samples/client/petstore/typescript-fetch/builds/oneOf-kebab-case/package.json">

<violation number="1" location="samples/client/petstore/typescript-fetch/builds/oneOf-kebab-case/package.json:19">
P2: The sample advertises TypeScript `^4.0`, but its generated runtime uses the `override` keyword, which was introduced in TypeScript 4.3. Builds that resolve TypeScript 4.0–4.2 will fail to parse `runtime.ts`; the dependency range could be raised to `^4.3 || ^5.0` (or the `override` modifiers could be removed).</violation>
</file>

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

if (json == null) {
return json;
}
if (typeof json !== 'object') {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Malformed primitive responses are returned as TestResponse: this early guard accepts numbers and booleans even though this union only permits string. Handle the allowed string explicitly, then reject other primitives so runtime deserialization matches the declared union.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/typescript-fetch/builds/oneOf-kebab-case/src/models/test-response.ts, line 45:

<comment>Malformed primitive responses are returned as `TestResponse`: this early guard accepts numbers and booleans even though this union only permits `string`. Handle the allowed string explicitly, then reject other primitives so runtime deserialization matches the declared union.</comment>

<file context>
@@ -0,0 +1,82 @@
+    if (json == null) {
+        return json;
+    }
+    if (typeof json !== 'object') {
+        return json;
+    }
</file context>

"prepare": "npm run build"
},
"devDependencies": {
"typescript": "^4.0 || ^5.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The sample advertises TypeScript ^4.0, but its generated runtime uses the override keyword, which was introduced in TypeScript 4.3. Builds that resolve TypeScript 4.0–4.2 will fail to parse runtime.ts; the dependency range could be raised to ^4.3 || ^5.0 (or the override modifiers could be removed).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/typescript-fetch/builds/oneOf-kebab-case/package.json, line 19:

<comment>The sample advertises TypeScript `^4.0`, but its generated runtime uses the `override` keyword, which was introduced in TypeScript 4.3. Builds that resolve TypeScript 4.0–4.2 will fail to parse `runtime.ts`; the dependency range could be raised to `^4.3 || ^5.0` (or the `override` modifiers could be removed).</comment>

<file context>
@@ -0,0 +1,21 @@
+    "prepare": "npm run build"
+  },
+  "devDependencies": {
+    "typescript": "^4.0 || ^5.0"
+  }
+}
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant