'"Herding" objects by "value branding" in Typescript
Is it possible in Typescript to transfer the uniqueness of a Symbol() to a container type and from there to the objects stored therein such that objects stored in one instance of the container type cannot be stored in another? Something like this is pretty close:
class Branded<T, B> {
constructor(readonly value: T, readonly brand: B) {}
}
class Container<T, B extends symbol> {
// mark the container with a symbol
constructor(readonly brand: B) {}
// somehow get a branded T out of the container
getOrCreate(...): Branded<T, B> {...}
// store only Branded values
// the goal would be to allow only values that were handed out of
// this particular object, but see below
store(v: Branded<T, B>): void {...}
}
// create two containers from the same symbol
const brand = Symbol();
const c1 = new Container(brand);
const c2 = new Container(brand);
// cannot avoid that this works, but it should not:
c1.store(c2.getOrCreate(...));
Is there a chance to let the compiler complain on the last line. The goal is that a Container object is as unique as a symbol and "herds" only the Branded values it hands out, with no intermingling with values from other containers. It seems to require that the symbol in brand can only be used once or that it is internal to Container.
Solution 1:[1]
The solution I found is a bit of a workaround, but sufficiently practical to be used.
- Make the constructor of
Containerprivate. - Provide a static factory method which returns always the same
Containerfor a given brand by keeping a staticMapfrom brand symbols toContainerobjects.
The name of the method and its documentation should make clear that a "singleton" per brand is returned, i.e. all invocations with the same brand symbol will return one and the same instance.
I call this "a bit of a workaround", because the compiler will still not complain in the last line as asked for, but now it is inconsequential since both variables from the question, c1 and c2, reference the same container object. Objects "herded" by one container are not entering a different one.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Harald |
