The way we've modeled tagged enums are with a frozen object containing a class for each Variant.
So this would translate to:
type Dog = …; // Dog defined elsewhere
type Cat = …;
const Animal = (() => {
class Dog {
constructor(public value: Dog) {
// This Dog value is the wrong type!
// value is the type of the Variant class.
}
}
class Cat {
constructor(public value: Cat) {}
}
return Object.freeze({ Dog, Cat });
})();
This commit changes the naming of the Variant class:
type Dog = …; // Dog defined elsewhere
type Cat = …;
const Animal = (() => {
class Dog_ {
constructor(public value: Dog) {
// There is no variant class called Dog yet, just Dog_,
// so value is the correct type.
}
}
class Cat_ {
constructor(public value: Cat) {}
}
// We rename the Dog_ variant class as Dog here,
// so the only way to access this class is via Animal.Dog.
return Object.freeze({ Dog: Dog_, Cat: Cat_ });
})();
According to The Big O of Code Reviews, this is a O(n) change.
This small PR tweaks the Variant classes for our typescript version of Tagged Enums, to allow Variants to have names of existing types.
For example, it's not uncommon for Rust programs to have enums constructed like so:
The way we've modeled tagged enums are with a frozen object containing a class for each Variant.
So this would translate to:
This commit changes the naming of the Variant class: