[BUG][typescript-fetch] Nested oneOf: parent imports instanceOf<Member> that is never emitted (TS2724/TS2305)

Ouverte
#25,274 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@Utkarsh-rwt y travaille déjà.

Depuis le 16/10/2026.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
35/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
java, openapi, typescript
Domaine
api, cli

Piste de recherche

The bug sits in the typescript-fetch template modelOneOf.mustache, which imports instanceOf<Member> for each member in oneOfModels even when the member is itself a oneOf. Start by reproducing with the spec in the issue, then compare the generated Parent.ts imports with the instanceOf functions Child.ts actually exports. Done means the generated client type-checks under strict mode, either by emitting instanceOfChild for discriminated oneOf models or by skipping the import when the function is absent.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
Description

When a oneOf schema has a member that is itself a oneOf (nested discriminated unions), the generated parent model does not compile. modelOneOf.mustache imports instanceOf<Member> for every member in oneOfModels, but for a member that is a oneOf model the generator never emits that function: only modelGeneric (and modelEnum) define instanceOf<Name>.

models/Parent.ts(18,5): error TS2305: Module '"./Child"' has no exported member 'instanceOfChild'.

With a discriminator the imported function is not even used by the parent (FromJSONTyped / ToJSON switch on the discriminator), so the build breaks only because of the import.

Related but different: #14611 (same missing import, with an enum member instead of a oneOf member).

openapi-generator version

Reproduced with v7.12.0, v7.16.0, v7.23.0, v7.26.0 and latest (7.27.0-SNAPSHOT). Not a recent regression as far as we can tell.

OpenAPI declaration file content or url
openapi: 3.0.0
info:
  title: nested oneOf
  version: 1.0.0
paths: {}
components:
  schemas:
    Parent:
      oneOf:
        - $ref: '#/components/schemas/Leaf'
        - $ref: '#/components/schemas/Child'
      discriminator:
        propertyName: type
        mapping:
          LEAF: '#/components/schemas/Leaf'
          CHILD: '#/components/schemas/Child'
    Child:
      oneOf:
        - $ref: '#/components/schemas/ChildA'
        - $ref: '#/components/schemas/ChildB'
      discriminator:
        propertyName: subType
        mapping:
          A: '#/components/schemas/ChildA'
          B: '#/components/schemas/ChildB'
    Leaf:
      type: object
      required: [type]
      properties:
        type: { type: string, enum: [LEAF] }
    ChildA:
      type: object
      required: [type, subType]
      properties:
        type: { type: string, enum: [CHILD] }
        subType: { type: string, enum: [A] }
    ChildB:
      type: object
      required: [type, subType]
      properties:
        type: { type: string, enum: [CHILD] }
        subType: { type: string, enum: [B] }
Generation Details
docker run --rm -v "$PWD":/x openapitools/openapi-generator-cli:latest generate \
  -i /x/spec.yaml -g typescript-fetch -o /x/out
npx -p [email protected] tsc --noEmit --strict --target es2020 --module commonjs \
  --moduleResolution node --lib es2020,dom out/models/Parent.ts
Steps to reproduce
  1. Generate with the spec and command above.
  2. Type-check out/models/Parent.ts: TS2305 on instanceOfChild.

Expected: the client compiles. Actual: Child.ts exports Child, ChildFromJSON, ChildFromJSONTyped, ChildToJSON, ChildToJSONTyped, but no instanceOfChild.

Suggest a fix

Either of these, in typescript-fetch/modelOneOf.mustache:

  • emit instanceOf{{classname}} for oneOf models with a discriminator, dispatching on the discriminator to the members' instanceOf functions. This is what we use today as a template override, and it works for us:

    {{#discriminator}}
    export function instanceOf{{classname}}(value: object): value is {{classname}} {
        if (!value || typeof value !== 'object' || !('{{discriminator.propertyBaseName}}' in value)) {
            return false;
        }
    
        switch ((value as any)['{{discriminator.propertyBaseName}}']) {
    {{#discriminator.mappedModels}}
            case '{{mappingName}}':
                return instanceOf{{modelName}}(value);
    {{/discriminator.mappedModels}}
            default:
                return false;
        }
    }
    {{/discriminator}}
    
  • or not import instanceOf<Member> when it is not used (the discriminator path) or does not exist (member is a oneOf/enum, which would also cover #14611).

Langage dominant
Java
Étoiles
26.9k
Forks
7.8k
Merge moyen
2 j 10 h
PR mergées (30 j)
180

Préparer son environnement

Ouvrir dans Codespaces

Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de OpenAPITools/openapi-generator

Toutes les issues de OpenAPITools/openapi-generator

Issues similaires

Plus d'issues Java

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.