[英]Typescript: super.super call on a protected method
我正在嘗試擴展/覆蓋 class 中的受保護方法,我們將ChildClass
稱為 class 庫的受保護覆蓋方法tapNode
在ParentClass
中,其方法調用super
到GrandParentClass
tapNode
我想覆蓋行為,以便ChildClass
可以在從ParentClass
擴展時調用grandParentClass
。
為了澄清,我們有
export class ChildClass extends ParentClass {
override tapNode(node?: TreeNode): void {
custom_stuff();
super.super.tapNode(node); //What I ideally want to do but can't
}
export class ParentClass extends ChildClass {
override tapNode(node?: TreeNode): void {
[ ...
inline class-specific code
... ]
super.tapNode(node);
}
export class GrandParentClass extends ParentClass {
override tapNode(node?: TreeNode): void {
[ ...
inline class-specific code
... ]
super.tapNode(node)
}
到目前為止我看過的一些方法:
我知道如何使用prototype
方法,但這似乎只適用於公共方法,而不是受保護的方法。 (有關該方法的更多信息,請參閱TypeScript super.super 調用)
我知道 mixins 和 ts-mixer,但這似乎只有在有唯一方法名稱的情況下才有效,因為您正在組合類。 (見Typescript:如何擴展兩個類? )
我知道如果將特定於類的代碼放入它自己的方法中,則覆蓋它的想法,但這僅適用於將代碼分離到它自己的方法中,而不是當它內聯時。 (以 https://stackoverflow.com/a/56536651/314780為例)。
我知道您通常不想這樣做!
如您所見, class
(和 ECMAScript,至少在撰寫本文時)中的 class inheritance 不支持此用例。
您還發現,一種可能的解決方法是回退到底層prototype
。 但是,對protected
的方法執行此操作會引發 TypeScript 錯誤(正如您所指出的,TS 僅允許對public
方法執行此操作)。
話雖如此,發出的 JS 代碼仍然包含prototype
上的protected
(甚至是private
!)方法,因為可見性修飾符僅在 TS 級別:
與 TypeScript 類型系統的其他方面一樣,
private
和protected
僅在類型檢查期間強制執行。這意味着 JavaScript 運行時構造(如
in
或簡單屬性查找)仍然可以訪問private
或protected
成員
因此,忽略 TS 錯誤,運行時按預期工作:
class GrandParentClass {
protected tapNode(node?: TreeNode): void {
/* ...
inline class-specific code
... */
console.log("GrandParent", node)
}
}
class ParentClass extends GrandParentClass {
override tapNode(node?: TreeNode): void {
/* ...
inline class-specific code
... */
console.log("Parent", node)
super.tapNode(node);
}
}
class ChildClass extends ParentClass {
override tapNode(node?: TreeNode): void {
//custom_stuff();
//super.super.tapNode(node); //What I ideally want to do but can't
console.log("Child", node)
// @ts-ignore In order to break the class inheritance contract,
// we have to break the TS visibility modifier contract as well...
GrandParentClass.prototype.tapNode.call(this, node)
// ~~~~~~~ Error: Property 'tapNode' is protected and only accessible through an instance of class 'ChildClass'. This is an instance of class 'GrandParentClass'.
}
}
new ChildClass().tapNode("some tree node")
type TreeNode = string
...正確輸出:
[LOG]: "Child", "some tree node"
// (No Parent log)
[LOG]: "GrandParent", "some tree node"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.