標籤:

求教:TypeScript override 父類的get set 報錯?

public A extends B

public set x(value:number)
{
super.x = value;
//下面去做另外的事情
}

會報錯:
"Only public and protected methods of the base class
are accessible via the super keyword.":
"通過 "super" 關鍵字只能訪問基類的公共方法和受保護方法。"

為什麼會這樣設計呢,有沒有辦法解決


TL; DR: 沒有解決方案。

不過至於原因,需要分情況討論。

題主既然能夠得到那個報錯,說明配置的 targetes5 或者更低。如果配置成 es2015 或以上的話 TypeScript 是完全不會報錯的。

相應的 PR 在 do not error on super property access in ES6 by vladima · Pull Request #5860 · Microsoft/TypeScript。

另外,由於 Accessor Property 不可能被編譯到 es3,所以題主唯一可能選用的 target 就是 es5

由於題目中並沒有給出 B 類的實現代碼,那麼有兩種可能性:

  1. B 類的 x 屬性是一個 Value Property;
  2. B 類的 x 屬性是一個 Accessor Property。

如果是情況 1,那麼這時候對 super.x 賦值等價於對 this.x 賦值,從而覆蓋 setter(Accessor 位於原型),所以第一次賦值之後 setter 便無法使用,顯然不符合需求。

這是由於 ECMAScript 本身的語義不允許操作 Base Class 的 Value Property,詳情參見 ES6 使用 super 訪問父類屬性,在 Chrome、Babel、TypeScript 不一致?。TypeScript 只是對 ECMAScript 的靜態類型檢查,並不添加或修改語義,所以這裡 TypeScript 無能為力。

此外如果忽略類型檢查錯誤,或者寫成 JavaScript 文件然後開 allowJS 的話也是可以對此進行編譯的,然而編譯結果是錯誤的,所以也不應該使用。詳情參見上述問題。

如果是情況 2,那麼就 ECMAScript 的語義而言是可以觸發到 B 類的 x 屬性的 setter 的,只是 TypeScript 目前還沒有提供支持。

對應的 Tracker 在 Allow to call getter/setter logic When subclassing · Issue #338 · Microsoft/TypeScript。

目前看來已經初步認可為 TypeScript 自身的問題,是一個合理的 Feature Request。不過具體實現方案已經討論了 3 年多了,目前還沒有有效結論,所以不要指望近期內能夠解決。

最近一次在 Design Meeting 中提及是 Suggestion Backlog Slog, 4/24/2017 · Issue #15356 · Microsoft/TypeScript:

#338 Allow super.get/set

not enough demand, too complex of code to gen, and cant be statically checked for correctness

應該不需要翻譯。

綜上,如果有編譯到 es5 的需求,那就別用 Super Property。另外也別黑 TypeScript,Babel 的實現一樣是錯的,只是因為沒有類型檢查才能編譯通過。


推薦閱讀:

Typescript玩轉設計模式 之 對象行為型模式(下)
TypeScript 的 Literal 類型
【RPU-A】Angular 開始支持 TypeScript 2.1
TypeScript入門
推斷函數返回值的類型

TAG:TypeScript |