在TypeScript中实例化新的HTMLElement

dan*_*cek 42 typescript

我试图在TypeScript中实例化新的HTMLDivElement

var elem = new HTMLDivElement();
Run Code Online (Sandbox Code Playgroud)

但浏览器抛出

Uncaught TypeError: Illegal constructor.
Run Code Online (Sandbox Code Playgroud)

解决方法似乎是使用

var elem = document.createElement('div');
Run Code Online (Sandbox Code Playgroud)

但由于种种原因,我觉得这个次优.

为什么我不能在lib.d.ts中有一个新的关键字时直接实例化DOM元素?

declare var HTMLDivElement: {
    prototype: HTMLDivElement;
    new (): HTMLDivElement;
}
Run Code Online (Sandbox Code Playgroud)

Rya*_*ugh 55

请注意,您在此处获得的错误是"非法构造函数".例如,这与您在编写时可能获得的"对象不是函数"错误不同new {}().

因此,从技术上讲,HTMLDivElement 确实有一个构造函数.只是这个特定的构造函数抛出异常而不是创建一个对象.

通常lib.d.ts只会排除这些无用的签名,但TypeScript要求instanceof运算符的右侧有一个构造函数.换句话说,写入是合法的foo instanceof HTMLElement,但不是foo instanceof [],并且差异取决于HTMLElement具有构造函数的事实.

桌上基本上有三种选择:

  1. 从DOM元素中删除构造签名并删除对instanceof右操作数的限制.这是不可取的,因为你真的更喜欢在有人意外编写代码x instanceof foo而不是x instanceof Foo(其中foo是实例Foo)的情况下捕获错误.
  2. 从DOM元素中删除构造签名,但保持instanceof检查到位.这很糟糕,因为foo instanceof HTMLElement写一个非常合理的东西.
  3. 当前的情况,构造函数存在但你必须知道不要调用它们.

你不能使用普通的构造函数构造DOM元素,因为你应该经历document.createElement.这基本上是出于与浏览器如何实现这些对象有关的技术原因.

  • 对于在`Element`的子类上调用构造函数的代码,从`tsc`添加警告或错误是否有意义? (4认同)
  • 惊人的解释。是否可以在 lib.d.ts 中发表评论来解释这一点?或者你不想用评论污染 lib.d.ts? (3认同)
  • `customElements.define( 'custom-tag', Thing );` 然后调用 `new Thing()` - 返回 `<custom-tag></custom-tag>` (2认同)

小智 9

你用c#语法错误的打字稿语法.

只需更换

var elem = new HTMLDivElement();
Run Code Online (Sandbox Code Playgroud)

宽度

var elem = document.createElement('div');
Run Code Online (Sandbox Code Playgroud)

要么

var elem = <HTMLDivElement>(document.createElement('div'));
Run Code Online (Sandbox Code Playgroud)

(如果需要使用HTMLDivElement属性)

  • 语法没有问题,这是一个语义问题. (12认同)

Nic*_*ell 5

如果您扩展HTMLElement或任何子类,如HTMLDivElement

您还需要注册自定义元素


class SampleDiv extends HTMLDivElement{
    constructor(){
       super();
    }
}
customElements.define('sample-div', SampleDiv, { extends: 'div' });
Run Code Online (Sandbox Code Playgroud)

在此处查看更多信息:https : //javascript.info/custom-elements