tjjfvi/subshape

Enable Specificity of Tag in Tagged Unions

Closed this issue · 0 comments

In the following example...

const c = s.taggedUnion(
  ["A"],
  ["B", ["B", s.str]],
  ["C", ["C", s.tuple(s.u32, s.u64)]],
);

... the JS union members are tagged via the key "_tag".

type C = {
  _tag: "A";
} | {
  _tag: "B";
  B: string;
} | {
  _tag: "C";
  C: [number, bigint];
}

However, what if one of the decoded fields is also keyed with "_tag"? In cases such as this (where user input is difficult to predict), the optimal solution is to use a symbol.

const Tag = Symbol.for("CTag");
type Tag = typeof Tag;

type C = {
  [_ in Tag]: "A";
} | {
  [_ in Tag]: "B";
  B: string;
} | {
  [_ in Tag]: "C";
  C: [number, bigint];
}

Note: this can cause faulty narrowing behavior. Nevertheless, it's a common use case.

With this in mind, should we introduce a new param of constraint type PropertyKey to precede members?

const c = s.taggedUnion(
+ "_tag",
  ["A"],
  ["B", ["B", s.str]],
  ["C", ["C", s.tuple(s.u32, s.u64)]],
);

... or ...

const Tag = Symbol.for("CTag");

const c = s.taggedUnion(
+ Tag,
  ["A"],
  ["B", ["B", s.str]],
  ["C", ["C", s.tuple(s.u32, s.u64)]],
);