I'm trying to enhance the Map class in JavaScript by adding a TypedMap subclass that extends the Map superclass.
TypeMap.js
export default class TypedMap extends Map {
#keyType;
#valueType;
constructor(keyType, valueType, entries) {
if (entries) {
for (let [k, v] of entries) {
if (typeof k !== keyType || typeof v !== valueType) {
throw new TypeError(`Wrong type for entry [${k}, ${v}]`);
}
}
}
super(entries);
this.#keyType = keyType;
this.#valueType = valueType;
}
set(key, value) {
if (this.#keyType && typeof key !== this.#keyType) {
throw new TypeError(`${key} is not of type ${this.#keyType}`);
}
if (this.#valueType && typeof value !== this.#valueType) {
throw new TypeError(`${value} is not of type ${this.#valueType}`);
}
return super.set(key, value);
}
}
main.js
import TypedMap from './TypedMap.js';
let entries = [
[1, 2],
[3, 4],
[5, 6],
];
let typedMap = new TypedMap('number', 'number', entries);
Error I'm getting
Uncaught TypeError: Cannot read private member #keyType from an object whose class did not declare it
at TypedMap.set (TypedMap.js?t=1696367023223:20:14)
at new Map (<anonymous>)
at new TypedMap (TypedMap.js?t=1696367023223:13:5)
at main.js?t=1696367092683:9:16
The #keyType and #valueType fields are private but I should still access them from within the class TypedMap but somehow that doesn't happen to be the case here.
I think it has something to do with the overridden set method because I added a test method in the TypedMap class and could access the private fields.
Can anyone explain what is happening here?
You have the problem that you call
super(entries)which callsthis.set()which needs your private properties. But they aren't defined yet inthis.The error message in Chrome is kind of misleading, in Firefox it's more meaningful:
That could mean that
thisisn't in a proper state ("not the right class"): the private properties are declared but not yet defined.On the other hand you cannot access
thisbefore callingsuper()to define your private props sincesuper()actually provides a properthiswith a proper prototype chain.So it's a deadlock. So add your entries manually.
Btw you can remove your type checking in the constructor since it's done in
set().