TypeScript導入
導入の経緯
C++のSTLをTypeScriptに移植したものがあるらしい、
そしてAtCoderで採用されているらしい、
うらやま!アルゴリズム、競技プログラミングでは明らかに恩恵がありそう、
あとそもそも(チーム)開発プログラミングではTypeScriptを使わない理由がない。
ES6の時のように「ブラウザ標準対応したら考えるのになー」、などと言ってられなくなってきた。
簡単に(gulpやwebpackとかで、設定ファイルを書かずに)使えるなら導入しよう
WDKへのTypeScript導入のメリット
オブジェクト設計が入る時に流用できる
型の部品化ができる
TypeScriptライブラリの恩恵を受けられる
VSCodeを使うと補完が便利
懸案事項
実装コストが上がらないか
strictを切ればJSとほぼ同じ、
修正してみた感じ、strictを入れる分にはそんなに面倒にならなそう、
めんどくさくならずに型付けを頑張る方法は調査中
変換のオーバーヘッド
→ 初期化、自動変換がそれぞれ1コマンドでできる(後述)
解決、JavaScriptのほぼ上位互換として使えそう
ts-node
Node.jsで実行する分にはコンパイルする必要がない。
JSへのコンパイル
ブラウザで動かす時用の対応
最新のTypeScriptをインストールする
インストールは割愛(brewを利用)
インストール後のバージョン確認
code: sh
% tsc -v
Version 3.9.7
起動
下記コマンドでTypeScript設定ファイルtsconfig.jsonを生成する
code: sh
% tsc --init
いろいろな項目があったりコメントアウトされている、moduleを変更する必要あり (後述)
tsconfig.jsonを作らないとwatchがうまく動作しなかった。
コンパイル先を./srcに設定、自動更新を掛ける
code: sh
tsc --outdir src -w
typescriptファイルは例えば./ts以下に作っていく
srcディレクトリ が存在しなくても自動で作ってくれる
フォルダ階層が守られる
ts/aaa/bbb.ts をコンパイルすると src/aaa/bbb.jsに
TypeScriptへの移行
1. 拡張子をjs -> tsに変える
2. エラーが出たところを修正
開発中の1プロジェクトでやってみたところ、特にエラーを握り潰さずに変換できた。
tsconfig.jsonについて
target
code: tsconfig.json
"target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
コンパイル後のJavascriptのバージョン、デフォルトはES3だが、今まで書いていたJavascriptと近いものがされるようES2015を設定
module
code: tsconfig.json
"module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
モジュールの管理方法について
es2015に設定しないと動作しなかった。
strict
デフォルトですべてのstrictオプションが有効になっている。
code: tsconfig.json
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
便利そうなので一旦そのまま、エラー解消しづらいところでは//@ts-ignoreをどんどん付けていく予定だが、煩わしさが勝てば無効化を検討
falseにすればほとんどJavascriptと変わらない気がする。
files/include
If the "files" and "include" are both left unspecified, the compiler defaults to including all TypeScript (.ts, .d.ts and .tsx) files in the containing directory and subdirectories except those excluded using the "exclude" property.
files, includeを省略するとexcludeに書かれていない全ディレクトリ 、サブディレクトリ のTypeScriptファイルがコンパイル対象に。
exclude
Files included using "include" can be filtered using the "exclude" property. However, files included explicitly using the "files" property are always included regardless of "exclude". The "exclude" property defaults to excluding the node_modules, bower_components, jspm_packages and <outDir> directories when not specified.
excludeを省略しても出力ディレクトリ やnode-modulesなどはコンパイル対象に入らないっぽい、便利
allowJs
JS files (.js and .jsx) are also included if allowJs is set to true.
JSファイルを含めたい時はallowJsをtrueに設定する
基本的に拡張子jsをtsに書き換えて適切に直せばコンパイル対象に含める必要はなさそう、既存ファイルの変換が面倒な時とかかな
moduleResolution
code: tsconfig.json
"moduleResolution": "node"
node-modulesによるライブラリ読み込みを実現するためにはこのオプションを設定する必要があるらしい
tsconfig.json
できあがったのがこちら、
code: tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"module": "es2015",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
tsc --initの代わりにこちらが生成されるようにすると良さそうです。
JS to TS
既存のJSファイルのエラーを握り潰しつつTypeScriptに一括置換したい時用のスクリプトがあった
移行については別記事にまとめる
TypeScript-STL
これがあればJavascript競技プログラミングのために用意したライブラリのいくつかはいらなくなりそう
Dequeへのshift(pop_front)が$ O(n)だったのが気になる
参考
こちらではstrict全無効からスタートしている