最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Extending TypeScript Map to restrict data type - Stack Overflow

programmeradmin3浏览0评论

I am trying to create a class FooMap that extends the default TypeScript Map class by restricting the type of parameters it accepts. The reason I am extending the Map class is because I want to write methods for that class that I will be accessing from different files.

The default Map class is Map<any,any>, however the FooMap class would be similar to a Map<number,Foo> using the built-in number type and user-defined Foo type. The FooMap would only accept these key/value pairs.

My attempt to to this was by passing a map in the constructor but I feel like there is a better way to do this.

// Say Foo class is defined as    
export class Foo {
    id: number;
    name: string;
}

Now, the FooMap class would be:

export class FooMap extends Map{
    constructor(otherMap : Map<number,Foo>){
        super(otherMap);
    }
}

But this does not work since super() only accepts an iterable, so there must be a better way to extend the Map class.

I am trying to create a class FooMap that extends the default TypeScript Map class by restricting the type of parameters it accepts. The reason I am extending the Map class is because I want to write methods for that class that I will be accessing from different files.

The default Map class is Map<any,any>, however the FooMap class would be similar to a Map<number,Foo> using the built-in number type and user-defined Foo type. The FooMap would only accept these key/value pairs.

My attempt to to this was by passing a map in the constructor but I feel like there is a better way to do this.

// Say Foo class is defined as    
export class Foo {
    id: number;
    name: string;
}

Now, the FooMap class would be:

export class FooMap extends Map{
    constructor(otherMap : Map<number,Foo>){
        super(otherMap);
    }
}

But this does not work since super() only accepts an iterable, so there must be a better way to extend the Map class.

Share Improve this question asked Jun 18, 2019 at 23:24 swopnilswopnil 3671 gold badge4 silver badges12 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 11

You need to make your class extending a fully instantiated generic Map as well:

export class FooMap extends Map<number, Foo> {

but to make it work you should target es6 (see https://github./Microsoft/TypeScript/issues/10853)

I am will extend zerkms' answer here with a succinct example:

tl;dr

  1. Create new class FooMap implementing Map<number, Foo>
  2. Add private inner Map<number, Foo>
  3. Expose all the functionality of the Map class

3a. Use IDE to declare all the interface functions of Map

3b. For each function return the inner Map's same function call

class OptionalMap <K, V> implements Map<K, V> {

    // Inner map
    private _innerMap: Map<K, V>;

    constructor(optionalFunctions: { fnName: string, fn: (value: V, ...args) => void }[]) {
        this._innerMap = new Map<K, V>();
        
        // My additional functionality to the standard Map. Note functionality is applied to this class not the inner Map
        if(optionalFunctions) {
            for (let optionalFunction of optionalFunctions) {
                if(this[optionalFunction.fnName]) {
                    throw new Error(`Reserved function name: ${optionalFunction.fnName}`);
                } else {
                    this[optionalFunction.fnName] = (key, ...args) => {
                        if(this.has(key)) {
                            optionalFunction.fn(this.get(key), ...args);
                        }
                    }
                }
            }
        }
    }

    // Exposing all the inner map's inherit functions here in implementing the interface 

    clear(): void {
        return this._innerMap.clear();
    }
    delete(key: K): boolean {
        return this._innerMap.delete(key);
    }
    forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void {
        return this._innerMap.forEach(callbackfn, thisArg);
    }
    get(key: K): V {
        return this._innerMap.get(key);
    }
    has(key: K): boolean {
        return this._innerMap.has(key);
    }
    set(key: K, value: V): this {
        this._innerMap.set(key, value);
        return this;
    }
    size: number;
    entries(): IterableIterator<[K, V]> {
        return this._innerMap.entries();
    }
    keys(): IterableIterator<K> {
        return this._innerMap.keys();
    }
    values(): IterableIterator<V> {
        return this._innerMap.values();
    }
    [Symbol.iterator](): IterableIterator<[K, V]> {
        return this._innerMap.entries();
    }
    [Symbol.toStringTag]: string;

}

export default OptionalMap;
发布评论

评论列表(0)

  1. 暂无评论