記事内に広告が含まれています

【ワレコの講座】JavaScriptをTypeScriptに移植でうっかりミス【解決】

この記事は約7分で読めます。
スポンサーリンク

以下、ワテ用の備忘録なので、皆さんにはあまり役に立たないかもしれない。

では、本題に入ろう。

スポンサーリンク
スポンサーリンク

JavaScriptのプログラムが収拾付かなくなって来た

このところ、猛烈にTypeScriptを習得している。

Visual Studio 2013の環境で過去に作成したJavaScriptのソースをTypeScript化しているのだ。

特にWarekoMapsプロジェクトなどを。

その理由は、JavaScriptのソースコードが2万行くらいになって来て、行き当たりばったりで機能を拡張してきたので収拾がつかなくなったのを修正しているのだ。

具体的に言うと、

  • グローバル変数名とローカル変数名が同じだったり
  • 関数の引数にもグローバル変数と同じ名前のものがあったり
  • 行き当たりばったりで即席で付けた関数名の規則性の無さ
  • 同じような機能の関数が複数の場所にあったり

と、もう、訳分からない状態になってしまったからだ。

悪いプログラミングの手本のような状態だ。

ワテの場合、CやC++などでコードを書いていると良くそういう状態になるのだが、通常は、もう少し早い段階でこういう問題は整理整頓してコードをスッキリさせている。

というよりは、ビルドでエラーが多発して修正せざるを得ない場合が多い。

 

ところが、JavaScriptはスクリプト言語なので、プログラムの中に多少問題があっても実行出来てしまう。

問題の箇所を実行した時には、その問題が発覚する場合もあるがそれまでは気付かない事も多い。

その結果、取り敢えず動くからと言う理由で、整理整頓をしないまま機能を継ぎ足して行った結果、こんな状態になってしまった。

あかん。

で、JavaScriptをオブジェクト指向に拡張したTypeScriptを使って書き換えているのだ。

 

で、先日、こんな失敗をした。

ワテの失敗

こんな感じの JavaScript のコードがあった。

"use strict";
 
window.onload = function () {
    func1(2);
}
 
function func1(n) {
 
    if (n == 1) {
        var obj = { 'parm1': 100 }
    } else if (n == 2) {
        var obj = { 'parm1': 200, 'parm2': 'オプションデータ' }
    } 
    func2(obj);
}
 
function func2(obj) {
    alert(JSON.stringify(obj));
}

ファイル: JavaScript.js

 

つまり func2(obj) はオブジェクト型の引数を取るのだが、objの中の要素の数が異なる場合がある。JavaScriptなら文法的には全く問題ない。

 

で、このコードを拡張子 .ts のファイル (TypeScript.ts) にコピペすると、二番目の var obj のところで

エラー    386    Subsequent variable declarations must have the same type.  Variable ‘obj’ must be of type ‘{ ‘parm1′: number; }’, but here has type ‘{ ‘parm1’: number; ‘parm2′: string; }’.

となる。

 

つまり、TypeScript の文法では一旦 obj という変数を宣言しているので、それとは別のデータ構造の変数 obj を別の場所で宣言する事は出来ないようだ。

なので、TypeScript.ts の中の func1(n) を即席で修正して、

function func1(n) {
 
    if (n == 1) {
        var obj = { 'parm1': 100 }
    } else if (n == 2) {
    //var obj = { 'parm1': 200, 'parm2': 'オプションデータ' }
      var obj2 = { 'parm1': 200, 'parm2': 'オプションデータ' }
    } 
    func2(obj);
} 

ファイル: JavaScript.ts

こんなふうにした .ts ファイルを作成した。

修正と言うよりは、単にエラーを回避したかっただけなので、手抜きでこんな事をしたと言うのが正しい。

これでエラーせずに TypeScript から JavaScript の生成が出来るようになるが、見ての通り n=2 で関数が実行された場合には、obj が未定義のままなので func2(obj) でエラーした(この例ではエラーしないが、実際の状況でエラーした)。

数十個の JavaScript ファイルを .ts 化している最中に、とりあえずエラー回避の為に即席でこういう修正をしたのだが、それが失敗だった。あとで修正するつもりだったのだが、忘れてしまったのだ。

分かってみると単純なミスなのだが。

 

正しくは、以下のように修正するべきだった。

        var obj;
        if (n == 1) {
            obj = { 'parm1': 100 }
        } else if (n == 2) {
            obj = { 'parm1': 200, 'parm2': 'オプションデータ' }
        }
        func2(obj);

この原因を突き止めるのに半日くらい掛かってしまった。

 

その理由は、Visual Studio で TypeScript をやるには、別の問題があるようなのだ。

ChromeブラウザーではTypeScriptがデバッグ出来ない?

ワテの場合、通常 JavaScript のをデバッグする場合には Chromeブラウザーを使う場合が多い。使い慣れているからだ。

F12を押すと、Developer Tools が開くのでその環境でデバッガーを使ってデバッグしている。

ところが、TypeScript や TypeScript から生成された JavaScript をそのChrome の Developer Tools でデバッグしようとしても、ブレークポイントをセットすると、何故かソースコードが表示されなくなってしまう。

理由は、良く分からん。

で、Internet Explorer11 で同じようにやってみると、問題なく出来る。なので TypeScript のデバッグでは、Internet Explorer11 を使っている。でも、あまり使い慣れていないので使い辛いのだ。

 

Chrome で TypeScript はデバッグ出来ないのか?

少しググッてみたところ、ここ↓で似たような質問を見かけた。

How to Get Full JavaScript/TypeScript Debugging in Chrome with Visual Studio (Like IE)

英語なので良く分からないが、やはり Chrome はダメで IE11 がお勧めと言う事かな?

現在ではVisual Studioでは問題無くTypeScirptをデバッグ出来る

その後、ワテの場合にはVS2017でTypeScriptを使うが、問題無くデバッグが出来る。

また、TypeScirptに関する原因不明のエラーなども出なくなり、非常に快適だ。

ワテが上の記事を書いていた当時はTypeScriptは1.8くらいのバージョンだったので、その当時は完成度も低くバグが多かったようだ。

現在では、バージョンも2.3くらいまで上がっているので、安定性も良い。

結論

結論としては、

  • ソースコードは、訳分からなくなる前に整理整頓するべき。
  • グローバル変数は多用しない。
  • 変数名、関数名は一貫性のあるネーミングを心掛ける。
  • TypeScript のデバッグには Chromeではなくて Internet Explorer 11 がお勧め。

と言う事だな。

今回のトラブルで半日くらい時間を費やしてしまった。

 

TypeScriptを習う

ネットで各種の解説記事で良く名前を見かける川俣さんの本だ。

 

Reactっていうのもあるんだよな。ワテはまだ使った事が無い。

 

こういう漫画風の本なら読み易いのだが…

スポンサーリンク
コメント募集

この記事に関して何か質問とか補足など有りましたら、このページ下部にあるコメント欄からお知らせ下さい。

JavaScriptTypeScript
スポンサーリンク
シェアする
warekoをフォローする
スポンサーリンク
われこ われこ

コメント