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

Aberta
#25,274 1 comentário 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

@Utkarsh-rwt já está trabalhando nisso.

Desde 16/10/2026.

Avaliação

Dificuldade
4/5
Tempo estimado
3-5 dias
Facilidade para iniciantes
35/100
Tipo de issue
Bug
Clareza
Razoavelmente clara
Status de atividade
Ativa
Stack de tecnologia
java, openapi, typescript
Domínio
api, cli

Direção de pesquisa

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.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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).

Linguagem predominante
Java
Estrelas
26.9k
Forks
7.8k
Merge médio
2d 10h
PRs com merge (30d)
180

Preparar o ambiente

Abrir no Codespaces

Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de OpenAPITools/openapi-generator

Todas as issues de OpenAPITools/openapi-generator

Issues semelhantes

Mais issues de Java

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.