Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,11 @@ private ExtendedCodegenModel processCodeGenModel(ExtendedCodegenModel cm) {
.map(CodegenComposedSchemas::getOneOf)
.orElse(Collections.emptyList());

// Type names omit branch nullability. Null is valid only when exactly one branch accepts it.
if (oneOfsList.stream().filter(cp -> cp.isNullable).count() == 1) {
cm.oneOf.add("null");
}

// create a set of any non-primitive, non-array types used in the oneOf schemas which will
// need to be imported.
cm.oneOfModels = oneOfsList.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.openapitools.codegen.typescript.TypeScriptGroups;
import org.openapitools.codegen.utils.ModelUtils;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.File;
Expand Down Expand Up @@ -752,6 +753,38 @@ public void testOneOfModelsDoNotImportPrimitiveTypes() throws IOException {
TestUtils.assertFileContains(testDiscriminatorResponse, "export type TestDiscriminatorResponse = { discriminatorField: 'optionOne' } & OptionOne | { discriminatorField: 'optionTwo' } & OptionTwo");
}

@DataProvider
public Object[][] nullableOneOfRuntimeCheckModes() {
return new Object[][] {{false}, {true}};
}

@Test(dataProvider = "nullableOneOfRuntimeCheckModes")
public void testNullablePrimitiveOneOfTypes(boolean withoutRuntimeChecks) throws IOException {
Map<String, Object> properties = new HashMap<>();
properties.put(TypeScriptFetchClientCodegen.WITHOUT_RUNTIME_CHECKS, withoutRuntimeChecks);
File output = generate(properties,
"src/test/resources/3_0/typescript-fetch/oneof-nullable-primitives.yaml");

for (String model : List.of("InlineNullableValue", "ReferencedNullableValue")) {
Path file = Paths.get(output + (withoutRuntimeChecks ? "/models/index.ts" : "/models/" + model + ".ts"));
TestUtils.assertFileContains(file, "export type " + model + " = null | number | string;");
}

// Null must match exactly one branch, rather than none or both branches.
for (String model : List.of("NonNullableValue", "MultipleNullableValue")) {
Path file = Paths.get(output + (withoutRuntimeChecks ? "/models/index.ts" : "/models/" + model + ".ts"));
TestUtils.assertFileContains(file, "export type " + model + " = number | string;");
}

Path arrayItems = Paths.get(output + (withoutRuntimeChecks
? "/models/index.ts" : "/models/NullableArrayItems.ts"));
TestUtils.assertFileContains(arrayItems, "export type NullableArrayItems = Array<string | null> | number;");

Path values = Paths.get(output + (withoutRuntimeChecks ? "/models/index.ts" : "/models/Values.ts"));
TestUtils.assertFileContains(values, "array: Array<InlineNullableValue>;",
"map: { [key: string]: InlineNullableValue; };");
}

/**
* Issue #21587
* When using oneOf, the Typescript Fetch generator should import modelled types except for
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
openapi: 3.0.3
info:
title: Nullable primitive oneOf values
version: 1.0.0
paths: {}
components:
schemas:
NullableString:
type: string
nullable: true
InlineNullableValue:
oneOf:
- type: string
nullable: true
- type: number
ReferencedNullableValue:
oneOf:
- $ref: '#/components/schemas/NullableString'
- type: number
NonNullableValue:
oneOf:
- type: string
- type: number
MultipleNullableValue:
oneOf:
- type: string
nullable: true
- type: number
nullable: true
NullableArrayItems:
oneOf:
- type: array
items:
type: string
nullable: true
- type: number
Values:
type: object
required:
- array
- map
properties:
array:
type: array
items:
$ref: '#/components/schemas/InlineNullableValue'
map:
type: object
additionalProperties:
$ref: '#/components/schemas/InlineNullableValue'
Loading