Allow array items in TypeScript to be nullable (#19157)

* Allow array items in TypeScript to be nullable

* Regenerate samples

* Remove duplicate nullable array items codegen
This commit is contained in:
CirnoV (Sickle) 2024-07-16 16:40:17 +09:00 committed by GitHub
parent 75e3be39cb
commit a81b736b24
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 40 additions and 59 deletions

View File

@ -629,7 +629,11 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
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" : "";

View File

@ -458,12 +458,8 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
@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";

View File

@ -804,10 +804,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
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) {
@ -825,10 +821,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
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;
@ -925,10 +917,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
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) {
@ -1022,16 +1010,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
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;
@ -1052,10 +1030,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
return TypeScriptFetchClientCodegen.itemsAreUniqueId(this.items);
}
public boolean itemsAreNullable() {
return TypeScriptFetchClientCodegen.itemsAreNullable(this.items);
}
public String getItemsDataType() {
return TypeScriptFetchClientCodegen.getItemsDataType(this.items);
}
@ -1206,10 +1180,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
return TypeScriptFetchClientCodegen.itemsAreUniqueId(this.items);
}
public boolean itemsAreNullable() {
return TypeScriptFetchClientCodegen.itemsAreNullable(this.items);
}
public String getItemsDataType() {
return TypeScriptFetchClientCodegen.getItemsDataType(this.items);
}

View File

@ -157,4 +157,15 @@ public class TypeScriptClientCodegenTest {
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>");
}
}

View File

@ -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; }}

View File

@ -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; }}

View File

@ -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; }}

View File

@ -76,7 +76,7 @@ export interface UpdatePetRequest {
export interface UpdatePetRegionsRequest {
petId: number;
newRegions: Array<Array<number>>;
newRegions: Array<Array<number | null>>;
}
export interface UpdatePetWithFormRequest {
@ -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();
}

View File

@ -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>>;
}

View File

@ -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>>;
}
/**

View File

@ -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; }}