Description
When a schema combines oneOf with sibling properties, ng-openapi-gen emits only a TypeScript union of the referenced types. The sibling properties are not reflected on the generated type.
When the same base fields are modeled with a separate schema and each variant uses allOf to extend it, generation works as expected (BaseDto & { ... } per variant). I want to confirm whether the first pattern is intentionally unsupported and whether the allOf approach is the recommended workaround.
I think it used to work with older versions but I could not confirm it.
Environment
ng-openapi-gen: 1.0.4, 1.0.5
OpenAPI: 3.0.x
Current behavior
Spec (simplified):
ResourceBaseDto:
type: object
properties:
resourceId:
type: integer
format: int64
resourceType:
$ref: '#/components/schemas/ResourceType'
resourceName:
type: string
FirmwareResourceDto:
type: object
properties:
file:
type: string
ResourceDto:
description: Polymorphic resource
oneOf:
- $ref: '#/components/schemas/FirmwareResourceDto'
- $ref: '#/components/schemas/OtherResourceDto'
properties:
resourceId:
type: integer
format: int64
resourceType:
$ref: '#/components/schemas/ResourceType'
resourceName:
type: string
Generated resource-dto.ts:
export type ResourceDto = FirmwareResourceDto | OtherResourceDto;
Common fields (resourceId, resourceType, etc.) are not on ResourceDto. Subtype files also only contain their own fields unless allOf is used
Expected behavior (question)
What is the intended way to model “polymorphic object with shared base fields” so that:
ResourceDto is a union of variants, and
consumers can access shared fields (e.g. resource.resourceId) with correct typing?
Merge sibling properties into the union (e.g. ResourceBaseDto & (A | B)), or include the shared properties within the variants.
Workaround that works today
Split base fields into ResourceBaseDto and reference it from each variant:
FirmwareResourceDto:
allOf:
- $ref: '#/components/schemas/ResourceBaseDto'
type: object
properties:
file:
type: string
ResourceDto:
oneOf:
- $ref: '#/components/schemas/FirmwareResourceDto'
- $ref: '#/components/schemas/OtherResourceDto'
Generated:
export type FirmwareResourceDto = ResourceBaseDto & { file?: string };
export type ResourceDto = FirmwareResourceDto | OtherResourceDto;
This satisfies our use case because every union member includes ResourceBaseDto, so resourceId is accessible on ResourceDto.
Impact
We generate our openapi yml direcly from the backend. The extra BaseDto has to be implemented within the backend code.
Questions
- Is oneOf + sibling properties on the same schema object supported? Was it supported once?
- Is allOf on each oneOf branch the recommended pattern for shared properties in OpenAPI 3.0?
- Would it make sense to emit export type ResourceDto = ResourceBaseDto & (A | B) when both oneOf and sibling properties are present, or is that considered invalid input?
Description
When a schema combines oneOf with sibling properties, ng-openapi-gen emits only a TypeScript union of the referenced types. The sibling properties are not reflected on the generated type.
When the same base fields are modeled with a separate schema and each variant uses allOf to extend it, generation works as expected (BaseDto & { ... } per variant). I want to confirm whether the first pattern is intentionally unsupported and whether the allOf approach is the recommended workaround.
I think it used to work with older versions but I could not confirm it.
Environment
ng-openapi-gen: 1.0.4, 1.0.5
OpenAPI: 3.0.x
Current behavior
Spec (simplified):
export type ResourceDto = FirmwareResourceDto | OtherResourceDto;
Common fields (resourceId, resourceType, etc.) are not on ResourceDto. Subtype files also only contain their own fields unless allOf is used
Expected behavior (question)
What is the intended way to model “polymorphic object with shared base fields” so that:
ResourceDto is a union of variants, and
consumers can access shared fields (e.g. resource.resourceId) with correct typing?
Merge sibling properties into the union (e.g. ResourceBaseDto & (A | B)), or include the shared properties within the variants.
Workaround that works today
Split base fields into ResourceBaseDto and reference it from each variant:
Generated:
export type FirmwareResourceDto = ResourceBaseDto & { file?: string };
export type ResourceDto = FirmwareResourceDto | OtherResourceDto;
This satisfies our use case because every union member includes ResourceBaseDto, so resourceId is accessible on ResourceDto.
Impact
We generate our openapi yml direcly from the backend. The extra BaseDto has to be implemented within the backend code.
Questions