TypeScriptのバージョン:4.9
Nodeのバージョン:18
Vite、terserを使用しています
1. 背景
業務のコードでTypeScriptを採用しています。
バージョンは4.9
です。
現在TypeScriptは5.4.5
が最新です。
ますます差が大きくなると上げづらくなる為、上げることになりました。
2. TypeScriptの破壊的変更を整理
5.0
関係演算子における暗黙の強制演算を禁止
TypeScriptの一部の操作では、暗黙の文字列から数値への強制を引き起こす可能性のあるコードを書くと、すでに警告が表示されます
function func(ns: number |string) {
return ns * 4; // Error, possible implicit coercion
}
5.0では、関係演算子 >
, <
, <=
, >=
にも適用されます。
functionfunc(ns: number |string) {
return ns > 4; // Now also an error
}
必要であれば、 +
を使って明示的にオペランドを number
に強制することができます
functionfunc(ns: number |string) {
return +ns > 4; // OK
}
5.1
ES2020とNode.js 14.17が最低ランタイム要件
TypeScript 5.1では、ECMAScript 2020で導入されたJavaScriptの機能が実装されています。
TypeScriptがNode.js 14.17以降でしか動作しないです。
5.2
最近のNode.jsの設定では、module
とmoduleResolution
が一致していなければならない
-module nodenext
を単独で使うか、-module esnext --moduleResolution bundler
を使った方がいいそうです。
"module": "ESNext",//esmodule と呼ばれるモジュール読み込みの解決方法
"moduleResolution":"bundler",//imports の相対パスにファイル拡張子を要求しない、変更してもファイルパスは既存のままでOK
5.3
インスタンス・プロパティに対する super
アクセスのチェック
super.プロパティアクセスによって参照される宣言がクラスフィールドである場合にエラーを出すようになりました。
5.3以前でもエラーが出ているのでもう少し調査してみます🙇♂️
5.4
破壊的変更はなかったです。
3. TypeScriptとVite関連のライブラリの関係から設定ファイルの設定値を検討
頭を整理するために図で関係するライブラリ、設定系を記載しました。
3.1. target
es2020
にしました
経緯
現状の設定:ES6
nodeのバージョンで利用可能なECMAScript機能のベースラインサポートを知ることができるそうです。
Node Target Mapping
適切なECMAScriptのバージョンを指定することでTypeScriptのコンパイルを可能な限り少なくできます
候補
-
es2022
クロスブラウザで使用可能のような記述が以下の記事でありましたが。それが定かかわからなかったのでcan i useで機能ごとに見ると、すると問題ないことがわかりました -
ESNext
- TypeScriptのバージョンがサポートする最も高いバージョン
- 異なるTypeScriptのバージョン間で同じ意味ではないため、アップグレードの予測が困難になる可能性があるそうです
ここで気づいたのですが、
minifyでterserを使用していました。
terserでecma2020までのものしかminifyされない為、今回はes2020にしました。
ecmaの型
terserOptions: {
ecma:2020,
},
3.2. module
es2020
にしました。
経緯
現状の設定:CommonJS
バンドルされるコードにはpreserveかesnextを指定すると書かれていました。
esnextはTypeScriptのバージョンによって異なるため、今回はes2020
と指定しています。
CommonJSスタイルで書かないため、preserve
は採用しませんでした。
3.3. moduleResolution
Bundler
にしました。
経緯
現状の設定:デフォルトの設定
バンドラを使用している為です。
node16 や nodenext のように、このモードは package.json の "imports" と "exports" をサポートしますが、Node.js の解決モードとは異なり、Bundler は imports のパスにファイル拡張子を要求しません
。
TypeScript で"moduleResolution": "Node"は使わないほうがいい
4. targetをes2020に変更して出たエラー
オブジェクトリテラルのキーの重複時にエラー
8進数のエスケープシーケンスでエラー
5. useDefineForClassFields
をtrue
にする
これをtrueにしないとトランスパイル時に、ブラウザで対応されてない静的初期化ブロックが書かれてしまいエラーになる恐れがあるらしいです。
これをtrue
にすると子クラスで親クラスのプロパティを上書きしようとしている際にエラーが出るようになリます。
class A {
value: number
}
class B extends A {
value: number
}
6. ビルド後のファイルを見る
ここでビルド後のファイルを見て意図していない変換がされていないか確認します。
7. 参考
- tsconfig.jsonを設定する
- tsconfig-cheat-sheet
- 【JavaScript】ES2022の新機能
- Typescript confusion: tsconfig.json module, moduleResolution, target & lib explained
- TypeScriptの設定の良し悪し
- 【TypeScript】tsconfig.jsonの主なオプションについて
- TypeScriptのmoduleオプションの話、あるいはTypeScript開発者の苦悩、あるいはCJSとESMの話
8. 最後に
tsconfig
の設定値や、vite.config
の設定を知る機会になりました
本記事を読んで頂き、ありがとうございました。
いいねいただけると記事執筆の励みになりますので、参考になったと思われた方は是非よろしくお願い致します🙏