Returning std::nullopt from the case of a TypeSwitch yields broken results, by either falling through to another case, or falling of the switch entirely and hitting an assertion. This is simply due to the use of operator= of what is now std::optional, which has an overload specifically for std::nullopt, causing the internal optional, used for the TypeSwitch result to be reset, instead of a value being constructed from the std::nullopt.
The fix is to simply use the emplace method of std::optional, causing a value to always be constructed from the value returned by the case function.