47190


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

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

[code]

    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();
    
[/code]

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

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


CC BY-SA 4.0
2018-08-02T01:39:32.420
47170
2018-08-03T12:03:43.517
2018-08-03T12:03:43.517
3054
29556
question
typescript
継承先クラスでは実装されているかも知れないメソッドを基底クラス内で扱いたい


BasicClassにgというプロパティが定義されていないから

> Property 'g' does not exist on type 'BaseClass'

というエラーが起きています。

"if (this.g)"という使い方をしているので、gの型はbooleanなのでしょう。

[code]

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

}

にgを定義する行を加えて

[code]

    class BaseClass {
        privaten g: boolean;
    h() {
        /* ... */
    }
    f() {
        if (this.g) {
            this.g();
            this.h();
        }
    }
    
[/code]

とすれば、とりあえずエラーは消えると思います。  
gに値を与える部分など、コードに追加すべきものが他にもあると思われます。


CC BY-SA 4.0
2018-08-02T03:13:11.527
47173
2018-08-02T03:13:11.527
217
47170
answer


TypeScriptは扱かったことがないので、オブジェクト指向的な考え方からの回答になります。

BaseClassに定義しているfメソッドは抽象メソッドとして定義を行うべきです。  
その後ExampleClassA、ExampleClassBでそれぞれでfメソッドの内容をオーバーライドして実装するべきだろうと考えます。

もしくは、BaseClassにgメソッドへの参照をなくし、ExampleClassA側のみfメソッドをオーバーライドして内部でgを呼ぶべきと考えます。

直接の回答ではありませんが、何か参考になれば幸いです。


CC BY-SA 4.0
2018-08-02T03:38:07.680
47174
2018-08-02T03:38:07.680
17014
47170
answer


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

[code]

    class BaseClass {
        g?(): void
    
[/code]

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

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


CC BY-SA 4.0
2018-08-02T09:38:21.627
47190
2018-08-02T09:38:21.627
3054
47170
answer