【问题标题】:Emulating abstract properties on a TypeScript class在 TypeScript 类上模拟抽象属性
【发布时间】:2013-11-14 00:50:02
【问题描述】:

TypeScript 本身没有“抽象”类。但是由于结构类型,接口有些弱。例如,当Y 是一个接口时,不能断言x instanceof Y

但是我注意到,未在构造函数中初始化的类字段的行为已经有点像抽象属性:它出现在类的 type 上,但它没有运行时存在,除非它实际上是分配的。这允许基类中的字段定义被子类中的属性定义“覆盖”,如Y 类在下面的示例中:

class X {
   // behaves somewhat like an abstract property
   i: number
}

class Y extends X {
   _i: number

   constructor () {
      super()
      this._i = 7
   }

   // Provide an "implementation" of i
   get i (): number {
      return this._i
   }

   set i (i: number) {
      this._i = i
   } 
}

另一方面,Z 通过分配给它使用继承的字段:

// This sub-class uses the inherited field.
class Z extends X {
   constructor () {
      super()
      this.i = 6
   }
}

如果我尝试通过new X 使用X 上的字段,则该字段未定义。在Y 的情况下,将获取覆盖属性。对于Z,使用继承的定义。

function testProp (): void {
   var x: X
   x = new X
   console.log(x.i) // undefined
   x = new Y
   console.log(x.i) // 7
   x = new Z
   console.log(x.i) // 6
}

这是 TypeScript 中“抽象属性”的合理方法吗?我希望能够断言x instanceof X 之类的东西(这排除了使用X 的接口),并且这个习语似乎对我有用。

【问题讨论】:

标签: properties typescript abstract


【解决方案1】:

解决方案停止工作的地方是当您注意到可以开始分配属性时...

var x: X = new X();
x.i = 5;
console.log(x.i);

这看起来不再抽象了。

为了防止这种情况,你可以开始使用这样的代码......

class Foo {
    get x(): number {
        return undefined;
    }

    set x(val: number) {
        // nothing
    }
}

但是,如果您对一大堆属性执行此操作,您的基类可能会开始膨胀。

【讨论】:

  • 或者set 可能会抛出AbstractMethodError
  • 是的——但本质上你需要在某处抛出错误——抽象方法也是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 2011-12-31
  • 1970-01-01
相关资源
最近更新 更多