2

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

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

问题是

  • Shape定义一个静态Utils
  • Shape间接继承自Curve
  • CurveUtils还定义了一个与签名无关的静态类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.Utilsinto的签名Shape.Utils,以便后者在结构上扩展前者。但是在文件中捕获基础three.js文件(此处)签名的“正确”方法是.d.ts什么?这是不正确使用继承的情况吗?

4

1 回答 1

2

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

语言规范第 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;
}
于 2013-10-26T10:39:21.560 回答