Код:

export class ExtendedMap<T, U> extends Map {
    constructor() {
        super();
    }

    toggle(key: T, value: U) {
        if (this.has(key)) {
            super.delete(key);
        } else {
            super.set(key, value);
        }
    }

    has(key: T): boolean {
        return super.has(key);
    }
}

Я получаю эту ошибку при компиляции ES5:

ERROR TypeError: Constructor Map требует 'new'

Я использую это так:

public registryLayers = new ExtendedMap<number, any>();

Фрагмент (без закомментированных частей TypeScript):

/*export*/ class ExtendedMap/*<T, U>*/ extends Map {
    constructor() {
        super();
    }

    toggle(key/*: T*/, value/*: U*/) {
        if (this.has(key)) {
            super.delete(key);
        } else {
            super.set(key, value);
        }
    }

    has(key/*: T*/)/*: boolean*/ {
        return super.has(key);
    }
}
/*public*/ registryLayers = new ExtendedMap/*<number, any>*/();
console.log("Worked without error");
0
Jessy 2 Мар 2021 в 14:24

1 ответ

Лучший ответ

Машинопись следует жаловаться Map, если вы таргетирования ES5 (он делает в этом примере ).

Если вы проигнорируете эту ошибку из TypeScript, а затем запустите код, который TypeScript генерирует в современном (ish) движке JavaScript, проблема в том, что созданный TypeScript код пытается вызвать Map как функцию конструктора в старом стиле. Когда вы настраиваете TypeScript для генерации кода ES5, он не генерирует конструкции class, потому что в ES5 их не было. Вместо этого он испускает синтаксис функции конструктора, и в вашем конструкторе ExtendedMap он пытается вызвать Map следующим образом:

return _super.call(this) || this; // Where `_super` is set to `Map`

Но в современной среде Map определяется как конструктор class и не может быть вызван таким образом, что приведет к ошибке, которую вы получаете.

Если вам нужно, чтобы ваш код работал в среде ES5, вам необходимо включить полифилл Map (поскольку Map не существует в ES5), который написан для совместимости со средой ES5, чтобы { {X2}} можно вызвать через .call, как указано выше. И если ваш код работает в современной (ish) среде, в которой уже есть Map, вам все равно потребуется включить полифилл из-за способа его вызова.

3
T.J. Crowder 2 Мар 2021 в 11:46