【问题标题】:Incompatible static properties in three.d.ts, with latest TypeScriptthree.d.ts 中的静态属性不兼容,与最新的 TypeScript
【发布时间】:2013-11-05 11:59:09
【问题描述】:

我正在使用 TypeScript develop 分支编译 three.d.ts(可从 here 获得)。我收到以下错误:

Types of static property 'Utils' of class 'THREE.Shape' and class 'THREE.Path'
are incompatible

问题是

  • Shape 定义了一个静态的Utils 类
  • Shape 间接继承自 Curve
  • Curve 还定义了一个静态 Utils 类,其签名与 Shape.Utils 无关

根据语言规范格式不正确。总结一下,three.d.ts 包含类似以下代码:

declare class A {
   static Utils: {
      f (): any;
   }
}

declare class B extends A {
   static Utils: {
      // incompatible with A.Utils, without f(): any
      g (): any;
   }
}

暂且不提为什么静态成员的类型必须与继承的同名静态成员的类型兼容的问题——这在其他几种 OO 语言中并非如此,但似乎确实如此在 TypeScript 中 - 我想知道如何修复 three.d.ts 以便我可以编译它。

我目前的解决方法是将Curve.Utils 的签名复制并粘贴到Shape.Utils 中,以便后者在结构上扩展前者。但是,在.d.ts 文件中捕获底层three.js 文件(here)的签名的“正确”方法是什么?这是继承使用不当的情况吗?

【问题讨论】:

  • 澄清:这在 TypeScript 0.9.1-1 下编译,但不在“开发”分支下。

标签: static three.js typescript


【解决方案1】:

简短的回答是,根据规范,Typescript 不允许成员通过继承隐藏,例如 C# 自动执行的操作。

如language specifications 8.2.3 节中所定义

派生类继承其未覆盖的基类的所有成员。继承意味着一个 派生类隐式包含基类的所有非覆盖成员。公共和私人 成员是继承的,但只有公共成员可以被覆盖。说派生类中的成员 当派生类成员具有相同的名称和种类时,覆盖基类中的成员 (实例或静态)作为基类成员。 覆盖成员的类型必须是子类型 (第 3.8.2 节)被覆盖成员的类型,否则会发生编译时错误。

和

基类静态成员可以被任何类型的派生类静态成员覆盖,只要 > 类型是兼容的,如上所述。

也许他们在最新的编译器版本中添加了一些以前缺少的类型检查...

这是一个基于继承的建议解决方案:

declare class UtilsA{
    f():any;
}
declare class UtilsB extends UtilsA{
    g():any;
}

declare class A {
   static Utils:UtilsA;
}

declare class B extends A {
   static Utils:UtilsB;
}

【讨论】:

  • 确实,这就是为什么我特别说“抛开问题......” :) 换句话说,鉴于这种情况,如何将three.js的这一方面正确编码为三个.d.ts 文件?
  • 澄清我给出的示例代码根据规范格式不正确。
  • 很好的答案。是的,您是正确的,因为他们添加了进一步检查以执行规范
  • @Roly 我认为如果您为 A 和 B 中的 Utils 定义一个类型,并且 B 中的 Utils 类型将是一个子类型(继承 Utils 的 A 类型),它会起作用。如果您只是定义相同的属性名称,Typescript 不允许这样做,您必须至少重命名这些属性中的一个,例如B.Utils B.在这种情况下,B 将有 Utils AND UtilsB
  • @Roly 在我的回答中添加了示例
猜你喜欢
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 1970-01-01
  • 2010-11-27
相关资源
最近更新 更多