Why this over the previous keyBy idea?
So this proposal currently tries to replace both the [compositeKey proposal](https://github.com/tc39/proposal-richer-keys) and [records/tuples](https://github.com/tc39/proposal-record-tuple) by introducing composite objects to fufill both purposes.
However as from the other issues this has a number of problems:
- keys can't be interned (and therefore `===` equal) without making some objects [unusuable in weakmaps](https://github.com/tc39/proposal-composites/issues/15)
- keys can't hide [private information](https://github.com/tc39/proposal-composites/issues/12) so it's hard to avoid leaking private details if used in a shared set/map
- keys have to be composites and so can't allow existing classes to opt-in to re-keying (no current issue, but `[[Prototype]]` issues are related)
These problems weren't suffered by the [previous keyBy](https://github.com/acutmore/proposal-keyby) proposal, and it's not clear to me how this proposal solves the problems of either records/tuples or key-ing better than that proposal.
For one in that proposal we could easily opt-in existing objects to the re-keying protocol:
```ts
class Point {
readonly x: number;
readonly y: number;
// ...constructor
[Symbol.reKey](): CompositeKey {
return new CompositeKey(this.x, this.y);
}
}
const s = Set.keyed();
s.add(new Point(3,4));
s.has(new Point(3,4)); // true
```
The proposal also had a pretty good path for record/tuples, just builtin objects with `reKey` in their prototype:
```ts
const r1 = #{ x: 10, y: 20 };
const r2 = #{ x: 10, y: 20 };
CompositeKey.equal(r1[Symbol.reKey](), r2[Symbol.reKey]());
// This could plausibly even be a dedicated function, which is essentially just
// equivalent to the above
Composite.equal(r1, r2);
```
Further if we were to use symbols [as suggested](https://github.com/acutmore/proposal-keyby/issues/5) we could even use `===` for composite key equality:
```ts
r1[Symbol.reKey]() === r2[Symbol.reKey](); // true
```
3 条评论