全局标识的元素,Typescript和仅限Safari的错误?

时间:2015-09-28 19:11:35

标签: javascript html dom safari typescript

假设你有一个像这样的选择元素:

<select id="Stooge" name="Stooge">
    <option value="0">Moe</option>
    <option value="1">Larry</option>
    <option value="2">Curly</option>
</select>

根据spec,当浏览器解析此页面时,它会创建一个全局范围的javascript变量window.Stooge。到目前为止一切都很好。

在我的TypeScript代码中,我想以强类型方式引用选项,所以我有以下内容:

enum Stooge
{
  Moe,
  Larry,
  Curly
}

这是像这样编译成javascript:

var Stooge;
(function (Stooge) {
    Stooge[Stooge["Moe"] = 0] = "Moe";
    Stooge[Stooge["Larry"] = 1] = "Larry";
    Stooge[Stooge["Curly"] = 2] = "Curly";
 })(Stooge || (Stooge = {}));  <---error here

我的问题是:在每个浏览器除了 Safari之外,这都可以。但在Safari中,我收到以下错误:

YourFile.js:[Line X]TYPE_MISMATCH_ERR: DOM Exception 17: The type of an object was incompatible with the expected type of the parameter associated to the object.

这只发生在一个恰好与DOM元素同名的枚举上,我想这是因为两个定义之间存在冲突,除了这个相同的代码不会导致除Safari之外的任何错误。

那么,为什么它在其他浏览器中有效呢?有没有办法在Safari中解决这个问题? (我可以重命名enum或DOM元素,但如果可能的话,我想避免使用人工命名约定。)

1 个答案:

答案 0 :(得分:2)

只要有可能,您应该避免在全球范围内放置任何内容。外部模块(很快将被重命名为更简单的名称,模块)是一种很好的方法。使用外部模块,您的enum将被安全地隐藏在模块的范围内,不应与其他任何内容发生冲突。

另一种解决方案是使用常量枚举,将其转换为普通数字(即删除枚举类型)。例如,以下TypeScript:

const enum Stooge
{
  Moe,
  Larry,
  Curly
}

var x = Stooge.Curly;

以下JavaScript中的结果:

var x = 2 /* Curly */;

您的最终选择是避免可能存在冲突的名称。将某些东西放在全球范围内时,尽可能减少碰撞风险是有帮助的。