-
-
Notifications
You must be signed in to change notification settings - Fork 512
Description
A more canonical way to do branding in modern JavaScript is Symbol.species. Javascript only defines Symbol.species when it appears as a static in a class (or as a property on a constructor function, which is the same thing). Putting it on the instance is not defined, but allowed. Basically, this is valid JavaScript code:
type Species<U, A> = {
"fp-ts/kind": U
"fp-ts/type": A
}
interface HKT<U, A> {
[Symbol.species]: Species<U, A>
}
const URI = "Test";
type URI = "Test";
class Test<A> implements HKT<URI, A> {
[Symbol.species]: Species<URI, A>
}
No more underscores (uses namespacing with "fp-ts/" instead) and no polluting the object. Advantage is that symbols are not enumerable at runtime, and they don't show up in keyof
at compile time, while still providing their function in constraints. the namespacing with "fp-ts" is optional of course, but I expect other libraries will start using Symbol.species in the future and as fantasy-land indicated, "namespace/" is kind of the canonical way to avoid collisions.