|
and &
in typesAllow the use of |
and &
without any types preceding them.
Occasionally, you will have many different types in a union or intersection type that exceeds a reasonable line limit and end up formatting it to avoid horizontal scrolling. Using the English alphabet as an example:
type EnglishAlphabet = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
Or you might just format it for readability:
type EnglishAlphabet = never
| "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m"
| "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
| "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"
| "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
Currently, there are two solutions to effect it:
=
to the next line=
on the line and add never
if using |
, or unknown
if using &
-- 1) union:
type Result<T, E>
= { tag: "ok", value: T }
| { tag: "err", error: E }
-- 2) union:
type Result<T, E> = never
| { tag: "ok", value: T }
| { tag: "err", error: E }
-- 1) intersection:
type MyOverloadedFunction
= ((string) -> number)
& ((number) -> string)
-- 2) intersection:
type MyOverloadedFunction = unknown
& ((string) -> number)
& ((number) -> string)
OCaml and TypeScript supports this same syntax:
type 'a tree =
| Leaf
| Node of 'a tree * 'a * 'a tree;;
type Tree<T> =
| { type: "leaf" }
| { type: "node", left: Tree<T>, value: T, right: Tree<T> };
This type becomes valid Luau syntax.
type Tree<T> =
| { type: "leaf" }
| { type: "node", left: Tree<T>, value: T, right: Tree<T> }
No drawbacks. The parser change is trivial. Instead of trying to parse a simple type and then calling Parser::parseTypeSuffix
, simply sense whether the current lexeme is |
or &
and directly invoke Parser::parseTypeSuffix
with nullptr
for the first type and making sure that nullptr
does not get pushed into the resulting vector. If the current lexeme is not |
or &
, then revert to current logic.
Don’t do this and accept one of the solutions already mentioned.