Description
7.15 Generates code that crashes at runtime for a required nullable datetime (and probably date too).
see: 65c3126
openapi-generator version
7.15, regression from 7.11 for sure, likely introduced when the linked commit went out in 7.14
OpenAPI declaration file content or url
{
"type": "object",
"properties": {
"startedAt": {
"type": "string",
"format": "date-time",
"nullable": true
}
},
"required": [
"startedAt"
]
}
Generation Details
generated with a command like:
java -jar bin/openapi-generator-cli-7.15.0.jar generate -i path/to/schema.json -g typescript-fetch -o path/to/apiGen -c bin/typescript.json
Generates code like:
'startedAt': ((value['startedAt'] as any).toISOString()),
which will crash when value['startedAt'] is null
Related issues/PRs
65c3126
#21133
#21132
#11307
Suggest a fix
|
{{#isDateType}} |
|
'{{baseName}}': {{^required}}value['{{name}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}(value['{{name}}']{{#isNullable}} as any{{/isNullable}}).toISOString().substring(0,10)), |
|
{{/isDateType}} |
|
{{#isDateTimeType}} |
|
'{{baseName}}': {{^required}}value['{{name}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}(value['{{name}}']{{#isNullable}} as any{{/isNullable}}).toISOString()), |
|
{{/isDateTimeType}} |
{{#isDateType}}
'{{baseName}}': {{^required}}value['{{name}}'] == null ? value['{{name}}'] : {{/required}}{{#isNullable}}{{#required}}value['{{name}}'] == null ? value['{{name}}'] : {{/required}}{{/isNullable}}value['{{name}}'].toISOString().substring(0,10),
{{/isDateType}}
{{#isDateTimeType}}
'{{baseName}}': {{^required}}value['{{name}}'] == null ? value['{{name}}'] : {{/required}}{{#isNullable}}{{#required}}value['{{name}}'] == null ? value['{{name}}'] : {{/required}}{{/isNullable}}value['{{name}}'].toISOString(),
{{/isDateTimeType}}
The theory is if something is not required AND nullable we kind of want to give the consumer freedom to pass in undefined OR null have have that value carry onto the server. Sometimes servers treat undefined or missing differently than null (for better or worse) so allowing either or is pretty important IMO. Otherwise if something is just not required its caught by the first block, and finally if something is nullable AND required then it is caught by the second block. you may notice the code is repeated, if mustache had an OR operator we could just do it in one block "if not required OR nullable -> do thing".
We don't need to cast it to any, typescript takes care of that via == null and type narrowing on the second branch of the conditional.
PR here: #21821
Description
7.15 Generates code that crashes at runtime for a
requirednullabledatetime (and probably date too).see: 65c3126
openapi-generator version
7.15, regression from 7.11 for sure, likely introduced when the linked commit went out in 7.14
OpenAPI declaration file content or url
{ "type": "object", "properties": { "startedAt": { "type": "string", "format": "date-time", "nullable": true } }, "required": [ "startedAt" ] }Generation Details
generated with a command like:
Generates code like:
which will crash when
value['startedAt']is nullRelated issues/PRs
65c3126
#21133
#21132
#11307
Suggest a fix
openapi-generator/modules/openapi-generator/src/main/resources/typescript-fetch/modelGeneric.mustache
Lines 142 to 147 in 29b6b77
The theory is if something is not required AND nullable we kind of want to give the consumer freedom to pass in undefined OR null have have that value carry onto the server. Sometimes servers treat undefined or missing differently than null (for better or worse) so allowing either or is pretty important IMO. Otherwise if something is just not required its caught by the first block, and finally if something is nullable AND required then it is caught by the second block. you may notice the code is repeated, if mustache had an OR operator we could just do it in one block "if not required OR nullable -> do thing".
We don't need to cast it to
any, typescript takes care of that via == null and type narrowing on the second branch of the conditional.PR here: #21821