継承先クラスでは実装されているかも知れないメソッドを基底クラス内で扱いたい

投稿者: Anonymous

昔JavaScriptで書いた変なコードをTypeScriptに置き換えようとしています。ですが Property 'g' does not exist on type 'BaseClass'. というエラーを回避できません。

オリジナルのコードのロジックを改変せずに、型定義や修飾子の追加で移行する方法を知りたいです。

class BaseClass {
    h() {
        /* ... */
    }
    f() {
        if (this.g) {
            this.g();
            this.h();
        }
    }
}

class ExampleClassA extends BaseClass {
    /* 継承してgメソッドを実装する場合 */
    g() {
        /* ... */
    }
}

class ExampleClassB extends BaseClass {
    /* 継承してもgメソッドを実装しない場合 */
}

/* BaseClassが直接呼ばれることはありません */
new ExampleClassA().f();
new ExampleClassB().f();

https://www.typescriptlang.org/play/ でも警告が出ることを確認しました)

型の追加では対応できない場合、どういう書き換えで乗り切ればよいか、よいアイディアがあれば教えてください。

解決

BaseClassg メソッドを以下のように宣言すればよさそうです。

class BaseClass {
    g?(): void

説明:
質問のコードから見るところ、g は「有っても無くてもよいメソッド」です。
「有っても無くてもよい」ことを表現する型で公式ドキュメントに説明が有るのは、Advanced Typesの「Optional parameters and properties」で、要するに ? を付ければよいとのこと。
そこでは触れられていませんが、メソッドもプロパティ等と同じように ? を付ければOptional になるようですので、上のコードとなります。

なお、Optional な型を使用する場合は strictNullChecks を有効にすることで、if (this.g) のようなチェックに漏れがないか確認できます。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *