错误 TypeError:构造函数映射在 ES5 中需要“new”?

1 javascript 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

ES5 编译时出现此错误:

错误类型错误:构造函数映射需要“新”

我这样使用它:

public registryLayers = new ExtendedMap<number, any>();
Run Code Online (Sandbox Code Playgroud)

片段(没有注释掉 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

如果您的目标是 ES5, TypeScript 应该会抱怨(在本例中Map确实如此)。

如果您忽略 TypeScript 中的错误,然后在现代 JavaScript 引擎中运行 TypeScript 生成的代码,则问题在于 TypeScript 创建的代码试图Map像旧式构造函数一样进行调用。当您配置 TypeScript 来发出 ES5 代码时,它不会发出class构造,因为 ES5 没有它们。相反,它发出构造函数语法,并且在ExtendedMap构造函数中,它尝试Map像这样调用:

return _super.call(this) || this; // Where `_super` is set to `Map`
Run Code Online (Sandbox Code Playgroud)

但在现代环境中,Map被定义为class构造函数,不能以这种方式调用,从而导致出现错误。

如果你需要你的代码在 ES5 环境中运行,你需要包含一个Mappolyfill(因为MapES5 中不存在),它被编写为与 ES5 环境兼容,以便Map可以通过上面的方式调用.call。如果您的代码在已经具有 的现代环境中运行Map,您仍然需要包含 polyfill,因为它的调用方式。