> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/js/val/class/example/typedmap.md).

# TypedMap

subclass of Map that checks key/value types.

[JS](/web/js.md) ⟩ [value](/web/js/val.md) ⟩ [object](/web/js/val/obj.md) ⟩ [class](/web/js/val/class.md) ⟩ [example](/web/js/val/class/example.md) ⟩ TypedMap&#x20;

{% hint style="success" %}
key points：

* <mark style="color:red;">**must**</mark> call <mark style="color:yellow;">**superclass constructor**</mark> [`super()`](broken://pages/nZ68pcPPhrtuYGaVJ94T) <mark style="color:red;">**before**</mark> using [**this**](/web/js/concept/execution-context/this.md).
* use [`super.method()`](broken://pages/nZ68pcPPhrtuYGaVJ94T) to call <mark style="color:yellow;">**superclass methods**</mark> in subclass methods.
  {% endhint %}

{% tabs %}
{% tab title="💾 程式" %}

* replit ⟩ [TypedMap](https://replit.com/@pegasusroe/TypedMap#TypedMap.js)

```javascript
// superclass
class TypedMap extends Map {
    
    // private properties
    #keyType;
    #valueType;
    
    // ⭐ subclass constructor
    constructor(keyType, valueType, entries) {

        // ⭐ must init new object with `super()` first❗
        super();            // ⭐ superclass constructor

        // ⭐ now `this` is accessable.
        this.#keyType = keyType;
        this.#valueType = valueType;
        
        // type-check/add entries if `entries` provided
        if (entries) {
            // subclass uses its method to help set key/value pairs,
            // make sure all properties are fully intialized before doing this❗
            entries.forEach(([key, value]) => this.set(key, value));
        }
    }

    // ⭐ override superclass method❗
    set(key, value) {
        // type check first, throw error if failed.
        this.#typecheck(key, value);
        // then set [key, value] using superclass method
        super.set(key, value);        // ⭐ superclass method
    }

    // check types
    #typecheck(key, value) {
        
        //  ⭐ destructuring private fields not allowed❓
        // ---------------------------------------------------------
        // const {#keyType: keyType, #valueType: valueType} = this;
        //        ^^^^^^^^ (⛔ SyntaxError: Unexpected identifier)

        const keyType = this.#keyType;
        const valueType = this.#valueType;
        
        if (typeof key !== keyType || typeof value !== valueType) 
            throw new TypeError(`[${key}:${value}] is not of type [${keyType}:${valueType}]`);
    }
}

// export
module.exports = TypedMap;
```

{% endtab %}

{% tab title="💈範例" %}

```javascript
const TypedMap = require('./TypedMap.js');

// test run
const dict = new TypedMap('string', 'string');
dict.set('hi', 'hello');
dict.get('hi')            // 'hello'

// dict.set(1, 'one');
// TypeError: [1:one] is not of type [string:string]

const a = new TypedMap('number', 'string', [
    [1, 'one'], [2, 'two'],
]);

a.get(1)                  // 'one'
```

{% endtab %}

{% tab title="📗 參考" %}

* [ ] [JavaScript: The Definitive Guide](/web/master/ref/javascript-the-definitive-guide.md) ⟩ 9.5.2 Subclasses with extends and super&#x20;
  {% endtab %}
  {% endtabs %}
