Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TSConfigからTypeScriptの世界を覗く
Search
らいと
May 23, 2025
Programming
1.6k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TSConfigからTypeScriptの世界を覗く
TSKaigi 2025 登壇資料
https://2025.tskaigi.org/talks/light_planck
らいと
May 23, 2025
Other Decks in Programming
See All in Programming
スマートグラスで並列バイブコーディング
hyshu
0
260
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
120
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
13
6.3k
Agentic UI
manfredsteyer
PRO
0
200
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
13k
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
160
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1k
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
770
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.4k
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
180
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
8k
Featured
See All Featured
Everyday Curiosity
cassininazir
0
240
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
860
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
240
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
220
Speed Design
sergeychernyshev
33
1.9k
A designer walks into a library…
pauljervisheath
211
24k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
260
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
610
Typedesign – Prime Four
hannesfritz
42
3.1k
How to Think Like a Performance Engineer
csswizardry
28
2.7k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
Transcript
TSConfig から TypeScript の世界を覗く #tskaigi_leverages らいと(@light_planck ) TSKaigi 2025 (2025-05-23
)
TSConfig との出会い ts-jest のESM サポートの設定を見直すときに初めてTSConfig を変更した ts-jest はTypeScript のコードをJest でテストするためのツール
module オプションを CommonJS から ESNext に変更 tsconfig.json の最終更新が3 年前 メンテナンスしたい 最初はオプションが多くて何がなんだか分からない 調べていくうちにTypeScript の知識が付いた この発表の原点はこの経験にある。
話したいこと TSConfig の全体像 TSConfig のオプションを知ることで、TypeScript への理解が深まる TSConfig のメンテナンスについて
TSConfig とは何か TypeScript compiler (tsc )の振る舞いを規定するもの。 TypeScript はコンパイル時に以下のことを行う。 静的型検査 トランスパイル
TypeScript の処理の流れ true false (デフォルト) .ts TypeScript compiler noEmit? 型検査のみ実行
型検査 エラーあり エラーなし true false (デフォルト) 型エラー? noEmitOnError? トランスパイル 出力なし .js
TSConfig の全体像 tsconfig.json で設定可能なトップレベルのプロパティは以下の通り。 compilerOptions がTSConfig のオプションの大半を占める。 // tsconfig.json {
"files": ["src/main.ts"], // tsc が対象とするファイル "include": ["src/**/*"], // tsc が対象とするファイル(ワイルドカードでも指定可) "exclude": ["node_modules"], // include の対象ファイルのうち、除外したいファイル "extends": "./configs/base", // 別のTSConfig ファイルの継承 "references": [], // Project References の設定 "watchOptions": {}, // `tsc --watch` のときの設定 "typeAcquisition": {}, // JavaScript の型情報を取得するための設定 // コンパイラの挙動を規定するための設定 "compilerOptions": {} }
compilerOptions のカテゴリ compilerOptions のオプションは無数にあるが、その役割によってカテゴライズされている。 (プロパティで はない。 ) src/compiler/commandLineParser.ts でこの区分を category
というプロパティで管理していそうなの で、以降はこれをカテゴリと呼ぶことにする。
主要なオプション target , module , strict を理解すれば、 tsconfig.json をざっくり読める。 また、これら3
つのオプションを知れば、TypeScript の理解が深まる。 target => トランスパイル module => モジュールシステム strict => 型システム 以降では target と strict のうちの一つである strictFunctionTypes を見ていくことで、 トランスパイルと型システムというTypeScript の核心に接近したい。 ※ 主要かどうかの判断は筆者の主観です。
target カテゴリ: Language and Environment target はTypeScript をECMAScript のどのバージョンにトランスパイルかを指定するためのオプション。 設定可能な値は
ES3 , ES5 , ES6/ES2015 , ES2016 , …, ES2024 , ESNext がある。デフォルトは ES5 。 ESNext はTypeScript がサポートしている最新のECMAScript のバージョンになる。 TypeScript のバージョンを上げたら変わる可能性があるので注意が必要。
target TypeScript はトランスパイル時に以下のことを行う。 型情報の削除 型注釈・型エイリアス・interface 宣言 target に対応したECMAScript の構文変換 アロー関数・テンプレートリテラル・let/const
宣言・分割代入, … ただし、JavaScript のAPI の変換は行わない。 (ポリフィルの責務) Array.prototype.includes() Map や Set などのデータ構造 など。
target ES2016 ES5 (Downleveling ) // TypeScript const greet =
(name: string): string => { return `Hello, ${name}!`; }; const isIncluded = [1, 2, 3].includes(1); // JavaScript (ES2016) const greet = (name) => { return `Hello, ${name}!`; }; const isIncluded = [1, 2, 3].includes(1); // JavaScript (ES5) var greet = function (name) { return "Hello, ".concat(name, "!"); }; var isIncluded = [1, 2, 3].includes(1); // includes はES5 に対応していない
strict カテゴリ: Type Checking strict オプションは厳密に型検査したい場合に推奨されるオプションを全て有効にする。 2025 年5 月現在では以下のオプションが有効になる。 alwaysStrict
(トランスパイルしたJS に "use strict; を追加) strictNullChecks (null とundefined の厳格なチェック) strictBindCallApply ( bind 、 call 、 apply の厳格な型チェック) strictBuiltinIteratorReturns (組み込みイテレータの戻り値チェック) strictFunctionTypes (関数型の厳格なチェック) strictPropertyInitialization (クラスプロパティの初期化チェック) noImplicitAny (暗黙的な any 型を禁止) noImplicitThis (暗黙的な this の型付けを禁止) useUnknownInCatchVariables (catch 節での unknown 型の使用)
strictFunctionTypes カテゴリ: Type Checking 関数の引数の変性を 双変 から 反変 に変更するオプション。 以下の概念を理解すれば、上記の意味が分かる。
構造的型付け 構造的部分型 変性(共変・反変・双変)
構造的型付け(Structural typing ) TypeScript は型の互換性・等価性をオブジェクトの構造によって決定する。 これを構造的型付けと言う。 (Go などもこれに当たる) 構造的型付けの他には名前的型付けがあり、型の名前で互換性を決定する。 (Java,
PHP など) 上記の例ではAnimal とHuman で名前が異なるのでコンパイルエラーになる。 interface Animal { name: string; } interface Human { name: string; } const human: Human = { name: " 人間", }; const animal: Animal = human; // 構造が同じなので、コンパイルエラーにならない
部分型(Subtyping ) ある型Sub が別の型Super に包含されるような階層構造のとき、型Sub をサブタイプ(部分型) 、型Super をス ーパータイプと呼ぶ。 このとき、Sub
はSuper に互換性がある。Sub はSuper に置き換えられると言い換えてもよい。 型Sub が型Super の部分型であるとき、 Sub <: Super と書く。 Human はAnimal のサブタイプであり、Animal に対して互換性を持つので、以下のコードはコンパイルエラー にならない。その逆はコンパイラエラーとなる。 const human: Human = new Human(); const animal: Animal = human;
構造的部分型(Structural subtype ) 構造的型付けにおいてサブタイプである条件は、ある別の型の全てのプロパティとメソッドを安全に呼び出せ るかによって決定する。つまり構造に着目している。 以下の例では、Human はAnimal の全てのプロパティとメソッドを安全に呼び出せるため、Human はAnimal の
サブタイプ(部分型) 、Animal はHuman のスーパータイプである。 // スーパータイプ interface Animal { name: string; } // サブタイプ interface Human { name: string; read: () => void; } let human: Human = { name: " 人間", read: () => console.log(" 読んだ"), }; const animal: Animal = human; // 互換性があるので代入可能 human = { name: " ねこ" }; // Property 'read' is missing in type '{ name: string; }' but required in type 'Human'.
変性(Variance ) 変性はジェネリクス型において型パラメータのサブタイプ関係とジェネリクス型のサブタイプ関係を定義する 概念。 ジェネリクス型とは型引数を受け取り、別の型を構成する型。 Sub とSuper の配列の変性、つまり Array<Sub> と
Array<Super> のサブタイプ関係はTypeScript では Sub <: Super , Array<Sub> <: Array<Super> と定義されている。 サブタイプ関係の方向が一致しており、これを共変と言う。逆に方向が反転する場合は反変と言う。 interface Animal { name: string; } interface Human { name: string; read: () => void; } const humans: Human[] = [ { name: " 人間1", read: () => {} }, { name: " 人間2", read: () => {} }, ]; const animals: Animal[] = humans;
strictFunctionTypes 、再び TypeScript は strictFunctionTypes が false のとき、型引数の変性を共変・反変のどちらも許可する。これ を双変と呼ぶ。 しかし双変は以下のような場合があるため、危険である。
より多くのものを扱える関数は、より少ないものを扱う関数に置き換えられない。 // 共変 // H <: A // HumanFunction(H) <: AnimalFunction(A) const humanFunction1: HumanFunction = (human: Human) => console.log(human.read()); const animalFunction1: AnimalFunction = humanFunction1; animalFunction1({ name: " ねこ" }); // read を呼び出そうとしている! // 反変 // H <: A // AnimalFunction(A) <: HumanFunction(H) const animalFunction2: AnimalFunction = (animal: Animal) => console.log(animal.name); const humanFunction2: HumanFunction = animalFunction2; humanFunction2({ name: " 人間", read: () => {} }); // 特に問題はない
TSConfig のメンテナンスについて 最後に tsconfig.json を変更したのはいつですか? 本セッションが tsconfig.json を見直すきっかけになったら嬉しい。 ポイント strict
が true になっているか ECMAScript のバージョン Recommended なオプションを有効にしているか 最近のオプションの把握
strict がtrue になっているか TypeScript で型安全な開発を行うには strict オプションの有効化が必須。 strict が原因でコンパイルエラーが発生する場合、該当するオプションを個別に無効化し、修正後に有効に するなどのアプローチがある。無効にしているなら、絶対に有効化したい。
ECMAScript のバージョン target , lib が現在最新の ES2024 / ESNext になっているか?
(明確な理由があって最新にしていない場合は別) lib はJavaScript のAPI やDOM の型情報を指定するオプション。これが古いとAPI の型も古いままになってし まう。
Recommended なオプションを有効にしているか 公式が推奨しているオプション。 ただしTSConfig Reference から「Recommended 」でページ内検索して見つける必要がある。 大半はデフォルトで有効・ strict で有効なので、それ以外のオプションは以下がある。
exactOptionalPropertyTypes オプショナルプロパティにundefined の明示的代入を禁止する設定 esModuleInterop CommonJS とES6 モジュール間の互換性を改善する設定 skipLibCheck 型定義ファイル(.d.ts )の型チェックをスキップして高速化する設定
最近のオプションの把握 例えばV5.8 で追加されたオプションに erasableSyntaxOnly がある。カテゴリは Interop Constraints 。 Node.js 23.6
では、 --experimental-strip-types モードでTypeScript ファイルを直接実行することができ る。 (Experimental ) ただし、TypeScript 固有の構文が実行時セマンティクスを持たなければならない。 (型注釈のような簡単な消去 することができるものに限る) enum 宣言 実行時コードを含むnamespace やmodule クラスのパラメータープロパティ CommonJS のimport = やexport = 代入
参考文献 鈴木僚太『プロを目指す人のためのTypeScript 入門』技術評論社, 2022. 「TypeScript Documentation 」, https://www.typescriptlang.org/docs/ 「Structural type
system 」, https://en.wikipedia.org/wiki/structural_type_system 「Covariance and contravariance (computer science) 」, https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) 「サバイバルTypeScript 」, https://typescriptbook.jp/
まとめ TSConfig は多数存在するが、階層やカテゴリを意識すると見通しが良くなる target トランスパイル時に型情報の削除と構文の変換を行う JavaScript のAPI は変換しない strictFunctionTypes 関数の型引数を双変から反変に変更する
TSConfig のメンテナンス観点 strict が true になっているか ECMAScript のバージョンが最新か Recommended なオプションを有効にしているか 最近のオプションの把握
自己紹介 らいと TSKaigi 2025 スタッフ ソフトウェアエンジニア at Studyplus, Inc =LOVE
・文学