-
Notifications
You must be signed in to change notification settings - Fork 482
Generated JS missing null check when pattern matching JSON.Array and JSON.Object #8251
Description
Bug: Switch pattern matching on JSON.Array and JSON.Object generates incorrect JS when Null case is omitted
When pattern matching on JSON values with both Array and Object cases, the generated JavaScript incorrectly omits the null check, causing runtime failures
when the value is null.
Reproducible Example
This ReScript code generates incorrect JavaScript (missing null check):
let getSchedule = (dict, key) => {
dict
->Dict.get(key)
->Option.mapOr(None, schedule => {
switch schedule {
| JSON.Array(array) =>
Some(
array->Array.map(finalJson => {
let finalDict = finalJson->getDictFromJsonObject
mappingScheduleWithDict(finalDict)
}),
)
| JSON.Object(dict) => Some([mappingScheduleWithDict(dict)])
| _ => None
}
})
}Incorrect Output (Bug): this is not handling the null case which should go to the None
function getSchedule(dict, key) {
return Stdlib_Option.mapOr(dict[key], undefined, schedule => {
if (Array.isArray(schedule)) { // <-- Crashes if schedule is null!
return schedule.map(finalJson => mappingScheduleWithDict(LogicUtils.getDictFromJsonObject(finalJson)));
}
switch (typeof schedule) {
case "object" :
return [mappingScheduleWithDict(schedule)];
default:
return;
}
});
}Workaround - Adding explicit Null case generates correct code:
| Null | _ => NoneCorrect Output (with Null case):
if (schedule === null) {
return;
}Additional Evidence - Only Object case generates correct guards:
switch schedule {
| JSON.Object(dict) => Some([mappingScheduleWithDict(dict)])
| _ => None
}Correctly generates:
if (typeof schedule === "object" && schedule !== null && !Array.isArray(schedule))Expected Behavior
When both Array and Object cases are present without explicit Null, the compiler should still emit the null check before Array.isArray() to prevent runtime
errors, consistent with the single Object case behavior.
Environment
- ReScript version: 12.0.0
- OS: macOS / Linux