Difference between union of true & false vs boolean validators?

I recently wrote a ValueToValidator type which converts a Convex Value into its corresponding Convex Validator. It was quite tricky to write, but it's now almost entirely functional, save one small inconsistency.

type Boolean = ValueToValidator<boolean>
// ✅ VBoolean<boolean, "required">

type UnionOfBooleanLiterals = ValueToValidator<true | false>
// 🟡 VBoolean<boolean, "required">

type UnionIncludingBoolean = ValueToValidator<string | boolean>
// 🟡 VUnion<string | boolean, [
//      VLiteral<false, "required">,
//      VLiteral<true, "required">,
//      VString<string, "required">
//    ], "required", never>


I don't think that the boolean type and true | false type literals are distinguishable (but if you think I'm wrong about that please let me know), so I think the best I could probably do is ensure that true | false is always translated to VBoolean<boolean, "required">. But that got me thinking—how does Convex represent this at lower-levels? I assume boolean ultimately becomes true | false, but was curious to verify. Also, should VBoolean<boolean, "required"> (somehow) reduce to VUnion<boolean, [VLiteral<true, "required">, VLiteral<false, "required">]>?
Was this page helpful?