Bug Report Checklist
Description
As of 7.23.0, the typescript-fetch generator emits instanceOf type guards that fail to compile with error TS2590: Expression produces a union type that is too complex to represent when a model has many required properties whose name differs from baseName (e.g. snake_case JSON keys camelCased into the TS interface).
This is a regression introduced by #23497, which added a dual-key check guarded by hasSanitizedName in modelGeneric.mustache:
{{#hasSanitizedName}}
if ((!('{{name}}' in value) && !('{{baseName}}' in value)) || (value['{{name}}'] === undefined && value['{{baseName}}'] === undefined)) return false;
{{/hasSanitizedName}}
Because the function is a type predicate (value is {{classname}}) and each clause performs two indexed-access reads (value['camelCase'], value['snake_case']) against a parameter typed object, TypeScript computes a narrowed candidate union after every clause. For a model where most/all required fields are sanitized (any snake_case API), the union width grows past the compiler's internal limit and trips TS2590. Skinny models stay under the threshold; wide models (≈15+ sanitized required props) fail.
APIs that serialize snake_case are hit on nearly every model, since name !== baseName for essentially every field.
openapi-generator version
7.23.0 (regression introduced in this version; 7.22.0 and earlier generate compilable guards). Latest release at time of filing.
OpenAPI declaration / minimal spec
openapi: 3.0.3
info:
title: repro
version: 1.0.0
paths:
/thing:
get:
operationId: getThing
responses:
'200':
description: ok
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
components:
schemas:
Thing:
type: object
properties:
aws_region: { type: string }
aws_account_name: { type: string }
aws_account_number:{ type: string }
created_at: { type: string }
updated_at: { type: string }
# ...repeat enough snake_case required props to cross the union limit (~15+)
required:
- aws_region
- aws_account_name
- aws_account_number
- created_at
- updated_at
Generation command
openapi-generator-cli generate -i repro.yaml -g typescript-fetch -o ./out
cd out && tsc --noEmit
Generated output (abbreviated)
export function instanceOfThing(value: object): value is Thing {
if ((!('awsRegion' in value) && !('aws_region' in value)) || (value['awsRegion'] === undefined && value['aws_region'] === undefined)) return false;
// ...one per required field...
return true;
}
tsc reports TS2590 on the value['...'] === undefined reads.
Steps to reproduce
- Generate the spec above with typescript-fetch on 7.23.0.
- Run tsc --noEmit against the output.
- Observe TS2590 on the instanceOf guard.
Suggested fix
A few directions (maintainers' call):
Related issues/PRs
Regression from #23497 (merged in 7.23.0).
Bug Report Checklist
Description
As of 7.23.0, the typescript-fetch generator emits instanceOf type guards that fail to compile with error TS2590: Expression produces a union type that is too complex to represent when a model has many required properties whose name differs from baseName (e.g. snake_case JSON keys camelCased into the TS interface).
This is a regression introduced by #23497, which added a dual-key check guarded by hasSanitizedName in modelGeneric.mustache:
{{#hasSanitizedName}}
if ((!('{{name}}' in value) && !('{{baseName}}' in value)) || (value['{{name}}'] === undefined && value['{{baseName}}'] === undefined)) return false;
{{/hasSanitizedName}}
Because the function is a type predicate (value is {{classname}}) and each clause performs two indexed-access reads (value['camelCase'], value['snake_case']) against a parameter typed object, TypeScript computes a narrowed candidate union after every clause. For a model where most/all required fields are sanitized (any snake_case API), the union width grows past the compiler's internal limit and trips TS2590. Skinny models stay under the threshold; wide models (≈15+ sanitized required props) fail.
APIs that serialize snake_case are hit on nearly every model, since name !== baseName for essentially every field.
openapi-generator version
7.23.0 (regression introduced in this version; 7.22.0 and earlier generate compilable guards). Latest release at time of filing.
OpenAPI declaration / minimal spec
Generation command
Generated output (abbreviated)
tsc reports TS2590 on the value['...'] === undefined reads.
Steps to reproduce
Suggested fix
A few directions (maintainers' call):
instanceOftype guards for discriminated unions #23497 but drop the dual name/baseName membership narrowing in favor of checking only baseName (the raw-JSON key) — which was the actual bug [typescript-fetch] FixinstanceOftype guards for discriminated unions #23497 targeted; orRelated issues/PRs
Regression from #23497 (merged in 7.23.0).