【TS】クラスのメソッドとプロパティは違うよって話
はじめに
今回はTypescript
で継承関係にあるクラスにおいて、親のメソッドをsuper
で呼び出した際に発生したエラーについてご紹介します。
原因が分かればなんてことない話だったのですが、思ったよりハマったので情報共有もかねて。
問題のコード
hoge
という関数を持つParentClass
と、それを継承したChildClass
の2クラスです。
ChildClass
のhoge
では、親であるParentClass
のhoge
を呼び出しています。
/**
* 親クラス
*/
class ParentClass {
hoge : () => void = () => console.log("Hoge");
}
/**
* 子クラス
*/
class ChildClass extends ParentClass {
hoge : () => void = () => {
super.hoge();
console.log("Hoge2");
}
}
const child = new ChildClass();
console.log(child.hoge()); // ---> "Hoge"のあとで"Hoge2"が表示されそうだが・・・?
"super"でエラーが出る
実は上記のコードだとChildClass
のhoge
内でエラーが出ます。
具体的には親クラスのhoge
を呼び出しているsuper.hoge()
の箇所で以下エラーとなります。
'super' キーワードを使用してアクセスできるのは、基底クラスのパブリック メソッドと保護されたメソッドのみです。ts(2340)
省略していますがhoge
自体はpublic
になっているので問題はなさそうです。
では、どのあたりが原因でこのエラーが出ているのでしょうか?
なぜエラーになる?
これはParentClass
のhoge
の書き方に問題があります。
アロー関数を使って今風な書き方をしていますが、これは実は 「クラスのプロパティ」 を定義していることになります。
super
で扱うことができるのは 「クラスメソッド」 なので、メソッドでないプロパティに対してsuper
を指定しても当該のエラーが発生するという仕組みです。
修正
ParentClass
のhoge
の書き方を修正します。
もともとあったアロー関数の書き方ではなく、クラス内メソッドとして定義します。
class ParentClass {
// これはプロパティ
//hoge : () => void = () => console.log("Hoge");
// これはメソッド
hoge() {
console.log("Hoge");
}
}
実行結果
Hoge
Hoge2
これで期待通りの結果になりました。
まとめ
今回はTypescript
の継承関係があるクラスにおけるプロパティとメソッドについて紹介しました。
ここ最近はReact
やReactNative
でも関数コンポーネントばかり書いているので、そもそもクラスを書く機会がなく、なかなか原因に気づけずにハマりました。
プロパティとして記載している場合でも動作はするので、super
等を使わない限りなかなか発生しにくいエラーだと思います。
Discussion