quicktype
quicktype copied to clipboard
[BUG]: (Dart) Null is better than empty array for null/undefined list-type properties
Issue Type
- quicktype output
Context (Environment, Version, Language)
Input Format: JSON Schema Output Language: Dart
CLI, npm, or app.quicktype.io: both Version: 23.0.170
Description
In DartRenderer.ts#L233, null/undefined value of a list-type property will fall back to an empty array.
However, some APIs, including ours, distinguish between null and [].
e.g. following is the simplified pseudocode.
{
"$ref": "#/definitions/API",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"API": {
"properties": {
"onlyFor": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
}
}
}
Coordinate(onlyFor: null).toJson(); // This will be `{onlyFor: []}`
This causes problems for the following logic:
type API = {
onlyFor?: string[];
};
function isEligible(res: API) {
const onlyFor = res.onlyFor;
if (onlyFor == null) return true;
return onlyFor.some((c) => c === process.platform);
}
Input Data
{
"$ref": "#/definitions/API",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"API": {
"properties": {
"onlyFor": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
}
}
}
Expected Behaviour / Output
class Coordinate {
List<String>? onlyFor;
Coordinate({
this.onlyFor,
});
factory Coordinate.fromJson(Map<String, dynamic> json) => Coordinate(
onlyFor: json["onlyFor"] == null ? null : List<String>.from(json["onlyFor"]!.map((x) => x)),
);
Map<String, dynamic> toJson() => {
"onlyFor": onlyFor == null ? null : List<dynamic>.from(onlyFor!.map((x) => x)),
};
}
Current Behaviour / Output
class Coordinate {
List<String>? onlyFor;
Coordinate({
this.onlyFor,
});
factory Coordinate.fromJson(Map<String, dynamic> json) => Coordinate(
onlyFor: json["onlyFor"] == null ? [] : List<String>.from(json["onlyFor"]!.map((x) => x)),
);
Map<String, dynamic> toJson() => {
"onlyFor": onlyFor == null ? [] : List<dynamic>.from(onlyFor!.map((x) => x)),
};
}
Steps to Reproduce
- Open https://app.quicktype.io/
- Set
Source typetoJSON Schema - Write Input Data as source
- Select Dart language in Options
- Confirm that
Null Safetyis turned on
Possible Solution
https://github.com/glideapps/quicktype/blob/be6a937dbfdc28ccffa771eefbe2c0b2e2f517fe/packages/quicktype-core/src/language/Dart/DartRenderer.ts#L233
- return [list, " == null ? [] : ", "List<", itemType, ">.from(", list, "!.map((x) => ", mapper, "))"];
+ return [list, " == null ? null : ", "List<", itemType, ">.from(", list, "!.map((x) => ", mapper, "))"];
We understand that this solution may impact existing APIs. So we want to explore if there is a better alternative.