【问题标题】:Using "open interfaces" to extend HTMLElement in TypeScript在 TypeScript 中使用“开放接口”扩展 HTMLElement
【发布时间】:2013-03-18 13:59:36
【问题描述】:

我想用其他方法扩展内置类 HTMLElement。也许我要疯了,但我认为以下是官方成语:

interface HTMLElement {
   swapChildBefore(remove: HTMLElement, insert: HTMLElement, before: HTMLElement): void;
}

HTMLElement.prototype.swapChildBefore =
   function (remove: HTMLElement, insert: HTMLElement, before: HTMLElement): void {
      this.removeChild(remove)
      this.insertBefore(insert, before)
   }

至少,根据How does prototype extend on typescript?,这样的事情应该可以工作。

但是,这似乎隐藏了 HTMLElement 上的所有现有方法。那是因为我声明了一个接口,它隐藏了同名的类吗?但是这个习语似乎适用于 Object 和 Array,它们也是类。

【问题讨论】:

  • HTMLElement 已经有一个以两个HTMLElement 为参数的swapChildBefore 方法。如果您想要具有三个参数的变体,则应该为该方法使用不同的名称。
  • 哦,好的。谢谢。 (不过,我无法通过 Google 搜索。唯一的搜索结果是这个 StackOverflow 问题。)

标签: typescript


【解决方案1】:

扩展接口必须在代码的根级别完成。如果您尝试在模块内扩展接口,则该模块内的代码将只能看到该范围内的接口。

破例:

interface ExpandableInterface {
    memberOfFIRSTDefinition: number;
}

module MyModule {
    interface ExpandableInterface {
        memberOfSECONDDefinition: number;
    }

    class MyClass {
        constructor() {
            var m: ExpandableInterface = {};
            m.memberOfFIRSTDefinition; // <-- It can't see this member because it's only scoped to the one inside of the module.
        }
    }
}

工作示例:

interface ExpandableInterface {
    memberOfFIRSTDefinition: number;
}

interface ExpandableInterface {
    memberOfSECONDDefinition: number;
}

module MyModule {
    class MyClass {
        constructor() {
            var m: ExpandableInterface = {};
            m.memberOfFIRSTDefinition; // <-- They're both root level, it can be seen :)
        }
    }
}

【讨论】:

  • 谢谢。其实我一开始就是这样,忘记改回来了。它应该有所作为吗?无论如何,我同意它作为常规方法签名更清晰,所以我编辑了我原来的问题。不过,问题仍然存在:似乎我通过引入此接口隐藏了 HTMLElement 类,这在扩展 Object 或 Array 时似乎不是这样。
  • 有趣。我粘贴的代码没有问题。您的接口定义是否在根代码级别内,而不是嵌套在模型等中?我怀疑这可能是范围问题。
  • 嗯,刚刚意识到它在一个模块内,如果我将定义提升到顶层,问题就会消失。我想这有点道理(我仍然习惯于打开接口)。如果您想将其发布为答案,我会接受。
  • 谢谢。我更新了我的回复,以正确回答您更新的问题和我们的发现:)
【解决方案2】:

它对我来说很好——在我声明了附加方法(使用不同的名称以不与现有的swapChildrenBefore 冲突)之后,TypeScript 编译器也对HTMLElement 的预先存在的属性和方法感到满意。见here

【讨论】:

    猜你喜欢
    • 2013-07-09
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 2020-06-09
    • 2020-04-09
    • 2017-03-04
    • 2020-10-30
    相关资源
    最近更新 更多