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

Đang mở
#25,274 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@Utkarsh-rwt đang làm issue này rồi.

Từ ngày 16/10/2026.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java, openapi, typescript
Lĩnh vực
api, cli

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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

Ngôn ngữ chính
Java
Star
26.9k
Fork
7.8k
Merge trung bình
2 ngày 10 giờ
Pull request đã merge (30 ngày)
180

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của OpenAPITools/openapi-generator

Tất cả issue của OpenAPITools/openapi-generator

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.