Typescriptにはstaticコンストラクタ的なのがないらしい

最近、謎にかな入力を練習し始めました。この記事もかな入力で書いています。
どうも、伊藤くんです。

この記事の内容は表題の通り、Typescriptにはstaticコンストラクタがないですよっていう話です。
あとその対処法について。

今回ぶち当たった問題

伊藤くん、以下のようなコードを書いていました。注目すべきはフィールドもメソッドもstaticであるというところ。

export default class Account {

private static accountData: Map<String, MyAccountData>;

public static getAccountData(id: string) {
return this.accountData.get(id);
}
}

んで、別クラスからAccount.getAccountData()を呼び出したらエラーに。

あ、そっか。Mapをnewしてないやと思って、コンストラクタでnewする処理書いたところで、ん?ってなった。
このgetAccountData()はstaticメソッドなため、このクラスがnewされる前、つまりコンストラクタが実行される前に呼び出される可能性があるのです。

あーこういう場合はstaticコンストラクタを使えばいいか。確かC#とかで書いたことあるなと思って、書いてみると・・・。

'static' modifier cannot appear on a constructor declaration.

むぇ???

なんかコンストラクタではstatic使えません的な雰囲気の英語が出てきました。

調べてみると、案の定Typescriptではstaticコンストラクタ的なのは無いそうな。

えー、、どうしろってんだいって感じでダメ元で

export default class Account {

private static accountData: Map<String, MyAccountData> = new Map(); // ここにnew書いてみた。

public static getAccountData(id: string) {
return this.accountData.get(id);
}
}

てな感じでいかにもnewとか許されなさそうな場所でnew書いてみたら、なんか普通にいけちゃいました。
こういうクラスの中のメソッド外のところで許されるのってせいぜいnumberとかstringの初期化くらいだと思ってました。

とは言っても、今回はただnewするだけだったから良かったものの、もうちょい複雑な処理をしてから初期化する場合などは、この方法ではできません。
んでいろいろ調べてみると、以下のような方法でいけるそうです。

export default class Account {

private static accountData: Map<String, MyAccountData> = (() => {

// 初期化に必要な処理とか

return new Map();
})();

public static getAccountData(id: string) {
return this.accountData.get(id);
}
}

これでプログラム実行時に実行されて、複雑な初期化ができるそうです。
参考:https://stackoverflow.com/questions/49589518/static-constructor-typescript

ふーむ。なるほど了解って感じですね。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です