Skip to content

Commit

Permalink
Allow array items in TypeScript to be nullable (#19157)
Browse files Browse the repository at this point in the history
* Allow array items in TypeScript to be nullable

* Regenerate samples

* Remove duplicate nullable array items codegen
  • Loading branch information
CirnoV authored Jul 16, 2024
1 parent 75e3be3 commit a81b736
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,11 @@ public String toModelFilename(String name) {
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
Schema<?> items = ModelUtils.getSchemaItems(p);
return getSchemaType(p) + "<" + getTypeDeclaration(unaliasSchema(items)) + ">";
String postfix = "";
if (Boolean.TRUE.equals(items.getNullable())) {
postfix = " | null";
}
return getSchemaType(p) + "<" + getTypeDeclaration(unaliasSchema(items)) + postfix + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema<?> inner = getSchemaAdditionalProperties(p);
String nullSafeSuffix = getNullSafeAdditionalProps() ? " | undefined" : "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,12 +458,8 @@ private String getHttpLibForFramework(String object) {

@Override
public String getTypeDeclaration(Schema p) {
Schema inner;
if (ModelUtils.isArraySchema(p)) {
inner = ModelUtils.getSchemaItems(p);
return this.getSchemaType(p) + "<" + this.getTypeDeclaration(unaliasSchema(inner)) + ">";
} else if (ModelUtils.isMapSchema(p)) {
inner = getSchemaAdditionalProperties(p);
if (ModelUtils.isMapSchema(p)) {
Schema<?> inner = getSchemaAdditionalProperties(p);
String postfix = "";
if (Boolean.TRUE.equals(inner.getNullable())) {
postfix = " | null";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -804,10 +804,6 @@ private boolean processCodegenProperty(ExtendedCodegenProperty var, String paren
newItemsDataType = "string";
var.dataTypeAlternate = var.dataTypeAlternate.replace("number", newItemsDataType);
}

if (var.itemsAreNullable()) {
var.dataTypeAlternate = var.dataTypeAlternate.replace(newItemsDataType, newItemsDataType + " | null");
}
} else if (var.isEnum) {
var.dataTypeAlternate = var.datatypeWithEnum;
} else if (var.isModel) {
Expand All @@ -825,10 +821,6 @@ private boolean processCodegenProperty(ExtendedCodegenProperty var, String paren
return parentIsEntity;
}

private boolean itemsAreNullable(ExtendedCodegenProperty var) {
return var.items.isNullable || (var.items.items != null && var.items.items.isNullable);
}

private void escapeOperationIds(OperationsMap operations) {
for (CodegenOperation _op : operations.getOperations().getOperation()) {
ExtendedCodegenOperation op = (ExtendedCodegenOperation) _op;
Expand Down Expand Up @@ -925,10 +917,6 @@ private void updateOperationParameterForSagaAndRecords(OperationsMap operations)
newItemsDataType = "string";
param.dataTypeAlternate = param.dataTypeAlternate.replace("number", newItemsDataType);
}

if (param.itemsAreNullable()) {
param.dataTypeAlternate = param.dataTypeAlternate.replace(newItemsDataType, newItemsDataType + " | null");
}
} else if (param.isEnum) {
param.dataTypeAlternate = param.datatypeWithEnum;
} else if (param.isModel) {
Expand Down Expand Up @@ -1022,16 +1010,6 @@ private static boolean itemsAreUniqueId(CodegenProperty items) {
return false;
}

private static boolean itemsAreNullable(CodegenProperty items) {
if (items == null) {
return true;
}
if (items.items != null) {
return itemsAreNullable(items.items);
}
return items.isNullable;
}

private static String getItemsDataType(CodegenProperty items) {
if (items == null) {
return null;
Expand All @@ -1052,10 +1030,6 @@ public boolean itemsAreUniqueId() {
return TypeScriptFetchClientCodegen.itemsAreUniqueId(this.items);
}

public boolean itemsAreNullable() {
return TypeScriptFetchClientCodegen.itemsAreNullable(this.items);
}

public String getItemsDataType() {
return TypeScriptFetchClientCodegen.getItemsDataType(this.items);
}
Expand Down Expand Up @@ -1206,10 +1180,6 @@ public boolean itemsAreUniqueId() {
return TypeScriptFetchClientCodegen.itemsAreUniqueId(this.items);
}

public boolean itemsAreNullable() {
return TypeScriptFetchClientCodegen.itemsAreNullable(this.items);
}

public String getItemsDataType() {
return TypeScriptFetchClientCodegen.getItemsDataType(this.items);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,15 @@ public void testCompilePattern() {
Assert.fail("Exception was thrown.");
}
}

@Test
public void arrayItemsCanBeNullable() throws Exception {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/array-nullable-items.yaml");
final DefaultCodegen codegen = new TypeScriptClientCodegen();
codegen.setOpenAPI(openAPI);
final ArraySchema schema = (ArraySchema) openAPI.getComponents().getSchemas().get("ArrayWithNullableItemsModel")
.getProperties()
.get("foo");
Assert.assertEquals(codegen.getTypeDeclaration(schema), "Array<string | null>");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1129,16 +1129,16 @@ export interface NullableClass {
'array_nullable_prop'?: Array<object> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
'array_and_items_nullable_prop'?: Array<object> | null;
'array_and_items_nullable_prop'?: Array<object | null> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
'array_items_nullable'?: Array<object>;
'array_items_nullable'?: Array<object | null>;
/**
*
* @type {{ [key: string]: object; }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -857,16 +857,16 @@ export interface NullableClass {
'array_nullable_prop'?: Array<object> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
'array_and_items_nullable_prop'?: Array<object> | null;
'array_and_items_nullable_prop'?: Array<object | null> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
'array_items_nullable'?: Array<object>;
'array_items_nullable'?: Array<object | null>;
/**
*
* @type {{ [key: string]: object; }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ export interface NullableClass {
arrayNullableProp?: Array<object> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
arrayAndItemsNullableProp?: Array<object> | null;
arrayAndItemsNullableProp?: Array<object | null> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
arrayItemsNullable?: Array<object>;
arrayItemsNullable?: Array<object | null>;
/**
*
* @type {{ [key: string]: object; }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export interface UpdatePetRequest {

export interface UpdatePetRegionsRequest {
petId: number;
newRegions: Array<Array<number>>;
newRegions: Array<Array<number | null>>;
}

export interface UpdatePetWithFormRequest {
Expand Down Expand Up @@ -509,7 +509,7 @@ export class PetApi extends runtime.BaseAPI {
/**
* Updates the pet regions.
*/
async updatePetRegions(petId: number, newRegions: Array<Array<number>>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<PetRegionsResponse> {
async updatePetRegions(petId: number, newRegions: Array<Array<number | null>>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<PetRegionsResponse> {
const response = await this.updatePetRegionsRaw({ petId: petId, newRegions: newRegions }, initOverrides);
return await response.value();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ export interface Pet {
status: PetStatusEnum;
/**
* An array of all 15-minute time slots in 24 hours.
* @type {Array<Array<number>>}
* @type {Array<Array<number | null>>}
* @memberof Pet
*/
regions?: Array<Array<number>>;
regions?: Array<Array<number | null>>;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ export interface PetRegionsResponse {
meta: ResponseMeta;
/**
* An array of all 15-minute time slots in 24 hours.
* @type {Array<Array<number>>}
* @type {Array<Array<number | null>>}
* @memberof PetRegionsResponse
*/
data?: Array<Array<number>>;
data?: Array<Array<number | null>>;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ export interface NullableClass {
arrayNullableProp?: Array<object> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
arrayAndItemsNullableProp?: Array<object> | null;
arrayAndItemsNullableProp?: Array<object | null> | null;
/**
*
* @type {Array<object>}
* @type {Array<object | null>}
* @memberof NullableClass
*/
arrayItemsNullable?: Array<object>;
arrayItemsNullable?: Array<object | null>;
/**
*
* @type {{ [key: string]: object; }}
Expand Down

0 comments on commit a81b736

Please sign in to comment.