6 ms·
Unfortunately this doesn’t work, at least not from a type safety perspective, because even without access to the symbol, nothing stops anyone from doing `let my
by jwalton 3y ago
Unfortunately this doesn’t work, at least not from a type safety perspective, because even without access to the symbol, nothing stops anyone from doing `let myFooId = 'foo' as any as FooId;`. You could detect this at runtime, but type safety is compile time.
- kristiandupont 3y agoSure, the TS type system is not sound but the idea is not to stop "bad guys", it's to help you realize you are doing something unintended.
- presentation 3y agoAgreed, for instance in our codebase we just make all type assertions a lint error demanding a justification, as well as flat out banning the any type. But anyone is free to write shoddy TypeScript.
- jwalton 3y agoThis is very true, but "helping you realize you are doing something unintended" works just as well with a string as with a symbol.
- WorldMaker 3y agoRight, hence "closest to" in my description. Typescript's role ends at compile time and it can't/won't stop bad actors at runtime. Typescript tries to make it easier for good actors to do the right thing more of the time. That said, the other benefit to using private symbols like this is that they are also easy to enforce at runtime, because symbol visibility is enforced at runtime (you can't create the same signal by hand somewhere else). It can be as easy as something like: console.assert(id.__brand__ === FooIdBrand) (That still won't stop the determined hacker in the console dev tools, if they can see a symbol they can create a reference to it, defense in depth will always be a thing.)