https://github.com/mrmarble/openapi-typescript-generator-one-of
https://github.com/mrmarble/openapi-typescript-generator-one-of
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/mrmarble/openapi-typescript-generator-one-of
- Owner: MrMarble
- Created: 2025-09-19T11:56:51.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-09-19T12:49:03.000Z (4 months ago)
- Last Synced: 2025-10-22T11:42:30.226Z (3 months ago)
- Language: TypeScript
- Size: 25.4 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# OpenAPI Generator TypeScript-Fetch OneOf Enum Bug
This repository demonstrates a critical bug in the OpenAPI Generator's TypeScript-Fetch generator where enum types are not properly generated when used within `oneOf` schemas under specific naming conditions.
https://github.com/OpenAPITools/openapi-generator/issues/21999
## Bug Description
The OpenAPI Generator fails to generate enum constants when **all** of the following conditions are met:
1. An enum schema is referenced within a `oneOf` construct
2. The enum schema name follows the pattern `{ModelName}{FieldName}` (e.g., `BuggyOneOfExampleSource` for model `BuggyOneOfExample` with field `source`)
3. The generator is set to `typescript-fetch`
When this occurs, instead of generating the actual enum constants, the generator creates a recursive type definition that references itself, making the enum unusable.
## Environment
- **OpenAPI Generator Version**: 7.15.0
- **Generator**: typescript-fetch
- **OpenAPI Specification**: 3.0.3
## Reproduction
1. Clone this repository
2. Run `npm install`
3. Run `npm run generate`
4. Examine the generated file `src/generated/models/index.ts`
## Test Scenarios
This repository includes three distinct scenarios to demonstrate the bug and working alternatives:
### 1. 🐛 Broken Scenario (`/broken-oneof`)
**OpenAPI Schema:**
```yaml
BuggyOneOfExample:
type: object
properties:
source:
oneOf:
- $ref: '#/components/schemas/BuggyOneOfExampleSource'
- $ref: '#/components/schemas/EmptyValue'
BuggyOneOfExampleSource:
type: string
enum:
- MANUAL
- SCANNER
- OTHER
```
**Problem**: The enum name `BuggyOneOfExampleSource` follows the `{ModelName}{FieldName}` pattern, causing the generator to fail.
### 2. ✅ Working Scenario (`/working-oneof`)
**OpenAPI Schema:**
```yaml
WorkingOneOfExample:
type: object
properties:
source:
oneOf:
- $ref: '#/components/schemas/CustomNamedSourceEnum'
- $ref: '#/components/schemas/EmptyValue'
CustomNamedSourceEnum:
type: string
enum:
- MANUAL
- SCANNER
- OTHER
```
**Solution**: Using a custom name `CustomNamedSourceEnum` that doesn't match the `{ModelName}{FieldName}` pattern works correctly.
### 3. ✅ Direct Reference Scenario (`/direct-reference`)
**OpenAPI Schema:**
```yaml
DirectReferenceExample:
type: object
properties:
source:
$ref: '#/components/schemas/DirectReferenceExampleSource'
DirectReferenceExampleSource:
type: string
enum:
- MANUAL
- SCANNER
- OTHER
```
**Solution**: Direct references (without `oneOf`) work correctly even when following the `{ModelName}{FieldName}` naming pattern.
## Generated TypeScript Code
After running `npm run generate`, examine `src/generated/models/index.ts` to see the difference:
### 🐛 Broken Output (BuggyOneOfExampleSource)
```typescript
/**
* @type BuggyOneOfExampleSource
*
* @export
*/
export type BuggyOneOfExampleSource = BuggyOneOfExampleSource | EmptyValue;
```
**Issue**: The enum constants (`MANUAL`, `SCANNER`, `OTHER`) are missing! Instead, there's a recursive type definition that references itself.
### ✅ Working Output (CustomNamedSourceEnum)
```typescript
/**
*
* @export
*/
export const CustomNamedSourceEnum = {
Manual: 'MANUAL',
Scanner: 'SCANNER',
Other: 'OTHER'
} as const;
export type CustomNamedSourceEnum = typeof CustomNamedSourceEnum[keyof typeof CustomNamedSourceEnum];
```
**Correct**: The enum constants are properly generated and usable.
### ✅ Working Output (DirectReferenceExampleSource)
```typescript
/**
*
* @export
*/
export const DirectReferenceExampleSource = {
Manual: 'MANUAL',
Scanner: 'SCANNER',
Other: 'OTHER'
} as const;
export type DirectReferenceExampleSource = typeof DirectReferenceExampleSource[keyof typeof DirectReferenceExampleSource];
```
**Correct**: Even with the `{ModelName}{FieldName}` pattern, direct references work fine.
## Impact
This bug makes it impossible to use properly named enum schemas within `oneOf` constructs, forcing developers to use non-intuitive naming conventions or restructure their API specifications.