microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.17k stars 12.38k forks source link

Symbol = LiveSymbol | DeadSymbol #59574

Open conartist6 opened 1 month ago

conartist6 commented 1 month ago

🔍 Search Terms

symbol weakmap TC39

✅ Viability Checklist

⭐ Suggestion

The latest version of ES creates a new kind of runtime error. It allows symbols to be used as weak map keys, but only some symbols. In particular it splits the symbol primitive in two. One one hand are "live" symbols, tracked by the garbage collector, and usable as weak map keys. Symbol() creates a live symbol. On the other had are "dead" symbols, such as Symbol.iterator, which return some value from Symbol.keyFor(sym) and are not legal keys for weak maps.

Since there are now fundamentally two incompatible primitive types, TS should adjust so that it is capable of catching these errors again.

📃 Motivating Example

const protos = new WeakMap();

const sym = Math.random() > 0.5 ? Symbol() : Symbol.for('me');

protos.set(sym, null); // crashes half the time

💻 Use Cases

Catching more errors

conartist6 commented 1 month ago

There is a related request for clarification from TC39 here: https://es.discourse.group/t/symbol-registration-and-weakmap-keying/2101/7

whzx5byb commented 1 month ago

Seems like a intended behavior, per https://github.com/microsoft/TypeScript/issues/52534#issuecomment-1424663656.

conartist6 commented 1 month ago

Even if the maintainers have considered this before I would like for it to have the weight of a formal feature request, so that demand for the feature may be tracked over the long term.

I presume that right now demand for the feature is basically zero since few to no people will be using symbols as weakmap keys in the wild yet. Once there is real damage to productivity from these kinds of errors I expect demand for the feature to begin to grow, and that demand can be tracked here.

RyanCavanaugh commented 1 month ago

Useful information would be how someone might accidently make this kind of error (apart from the very first time, which would statically fail)

Josh-Cena commented 1 month ago

Friendly reminder that Symbol.iterator is eligible as weakmap keys, because Symbol.iterator has similar garbage collection semantics as Array.prototype. Therefore in MDN (and also spec discussions, I think?) we use "non-registered symbol" for symbols that can be weakly held.