背景
学習がてら開発しているクライアントサイドのみの小さなSPAをJavaScriptで書いていたが、変数に入っているのが何のオブジェクトなのかがわからなくなって混乱してきたので重い腰を上げてTypeScriptに移行することに。
環境
Vue.jsを使ったJavaScript(ES6)のコードをWebPackで固めてクライアントサイドで実行している。
エディタはVSCode
typescriptとts-loaderモジュールのインストール
WebPackや各種モジュールを使うのにすでにnpmやNode.jsやWebPackはインストール済みなので、TypeScriptとそれをWebPackにロードするためのローダーのモジュールをnpmでインストールする。
$ npm i typescript ts-loader
webpack.config.jsの書き換え
既存のwebpack.config.jsファイルのmodule.rulesに.tsファイルのロードと解決に関する設定を追加したところ以下のようになった。
module.exports={mode:'development',module:{rules:[{test:/\.css$/,use:["style-loader","css-loader"]},{// .tsファイルをロードする設定を追加test:/\.ts$/,use:'ts-loader'}]},resolve:{alias:{'vue$':'vue/dist/vue.esm.js'},// 拡張子.tsのファイルをjsに変換// (この設定はファイル名の解決に使われるらしい。詳細を後述)extensions:['.ts','.js']},entry:'./src/index.js',output:{path:`${__dirname}/public`,filename:'main.js'},devServer:{contentBase:'./public'}}ts設定ファイルの追加
以下のようなtsconfig.jsonを追加しました。詳細は後述。
{"compilerOptions":{"target":"esnext","module":"commonjs",// "noImplicitAny": true, // 今まで書いたJSのコードで定義した変数がとりあえずそのまま使えるように"esModuleInterop":true,},}拡張子とソースコードの変更
JavaScriptで書かれたコードはそのままTypeScriptのコードとして通用すると言うことなので、以下のようなprogram.jsをprogram.tsにリネーム。
idやnumberのような仮引数に対して"Parameter 'id' implicitly has an 'any' type.ts(7006)
"と怒られた。tsconfig.jsonのnoImplicitAny : trueをコメントアウトすることで解消。
exportdefaultclassProgram{constructor(id,number,title,startTime,lengthMinute,unlockOffsetMinutes){this.id=id;this.number=number;this.title=title;this.startTime=startTime;this.lengthMinute=lengthMinute;this.unlockOffsetMinutes=unlockOffsetMinutes;this.isSelected=false;}/* 色々な処理が書かれているけど省略 */}すると、Property 'id' does not exist on type 'Program'.ts(2339)と怒られた。TypeScriptのクラス定義ではコンストラクタ外でプロパティの定義が必要らしい。VSCodeのQuick FixでDeclare propertyすることで解消。
exportdefaultclassProgram{id:any;number:any;title:any;startTime:any;lengthMinute:any;unlockOffsetMinutes:any;isSelected:boolean;constructor(id,number,title,startTime,lengthMinute,unlockOffsetMinutes){this.id=id;this.number=number;this.title=title;this.startTime=startTime;this.lengthMinute=lengthMinute;this.unlockOffsetMinutes=unlockOffsetMinutes;this.isSelected=false;}/* 色々な処理が書かれているけど省略 */}遭遇したエラー
Module not found: Error: Can't resolve './program' in '/Users/rlcl-226/git/gachi-taite-designer-web/src'
webpackが出したっぽいエラー../programと言うファイルを探した結果見つからなかったと言っているように見える。webpack.jsのresolve.extensionsの設定をすることで解消。
WebPackがprogram.jsを探しに来た時に、TypeScriptコンパイラがprogram.tsをコンパイルしたものを渡してあげるという設定だろうか?
終わりに
とりあえずTypeScriptへの移行の最初のファイルはこれで完了した。
これとは別のソースファイルをTypeScriptに移行しようとした時、moment-duration-formatでエラーが出て直したりしたが、それは別の記事に書くとする。