shared-tooling-typescript-config について
TypeScript の厳格な設定と共有 tsconfig のパターンを扱う実践ガイドです。新規作成や保守を行う開発者向けに、最新のモジュール設定、パスエイリアスの整合、プロジェクト別の設定選択を説明します。
主な機能
- 01厳格な型チェック設定
- 02モノレポ向け共有設定パターン
- 03最新のモジュール解決設定
- 04設定間のパスエイリアス同期
- 05TS 5.x・6.0 のオプション解説
活用シーン
- 01新規プロジェクトで厳格モードを有効化
- 02モノレポの各パッケージで tsconfig を統一
- 03バンドラーベースのモジュール設定
- 04非推奨オプションの移行と新機能の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agents-inc/ skills --skill shared-tooling-typescript-configインストール後、Claude Code で/shared-tooling-typescript-configを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.yamlreference.mdexamples/core.md詳細
TypeScript 設定パターン
クイックガイド: 共有 TypeScript 厳格設定は
packages/typescript-config/にあります。strict: trueに加えて、noUncheckedIndexedAccess、exactOptionalPropertyTypes、noImplicitOverrideを有効にします。最新のモジュール設定を使用します:module: "preserve"、moduleResolution: "bundler"、verbatimModuleSyntax: true、moduleDetection: "force"。移植可能なパスには${configDir}(TS 5.5+)を使用します。パスエイリアスを tsconfig とビルドツール間で同期します。
<critical_requirements>
重要:このスキルを使用する前に
(すべての tsconfig.json ファイルで TypeScript の strict モード(strict: true)を有効にする必要があります(必須))
(明示的な import type を強制するため、verbatimModuleSyntax: true を使用する必要があります。非推奨の importsNotUsedAsValues に代わる設定です)
(モノレポでは共有設定パターン(packages/typescript-config/)を使用する必要があります。パッケージごとに設定を重複させないでください)
(tsconfig.json とビルドツール間でパスエイリアスを同期する必要があります。不一致があるとインポート解決に失敗します)
(最新のモジュール設定を使用する必要があります。バンドラーを使用するプロジェクトでは module: "preserve" と moduleResolution: "bundler" を設定します)
</critical_requirements>
自動検出: TypeScript 設定、tsconfig.json、tsconfig、strict モード、noUncheckedIndexedAccess、exactOptionalPropertyTypes、verbatimModuleSyntax、moduleDetection force、module preserve、moduleResolution bundler、configDir、パスエイリアス、typescript-config、共有設定、noImplicitOverride、isolatedDeclarations、erasableSyntaxOnly、import defer
使用する場面:
- 新規または既存のプロジェクトで TypeScript strict モードを設定する
- モノレポ全体で一貫性を保つための共有 tsconfig パターンを作成する
- TS 5.x 以降の最新モジュール設定(preserve、bundler、verbatimModuleSyntax)を構成する
- tsconfig とビルドツール間でパスエイリアスを同期する
- 専用設定(React、Node.js、ライブラリの公開用)を作成する
- 非推奨の TypeScript オプションから移行する
- 新しい TS 機能(
isolatedDeclarations、erasableSyntaxOnly、configDir、import defer)を評価する
使用しない場面:
- 実行時の TypeScript コードパターン(言語/フレームワークのスキルを参照)
- リンターの設定(別のスキルを参照)
- ビルドツールの設定(別のスキルを参照)。ただし、パスエイリアスの同期に関するガイダンスはここに記載します
- 命名やインポートなど、日常的なコーディング規約(CLAUDE.md を参照)
対象となる主なパターン:
- モノレポの拡張パターンに対応した共有 strict 設定のベース
- 最新のモジュール設定(TS 5.x 以降:preserve、bundler、verbatimModuleSyntax、moduleDetection)
- 移植可能な共有設定のための
${configDir}テンプレート変数(TS 5.5+) - tsconfig とビルドツール間のパスエイリアスの同期
- 専用設定(react.json、node.json、library.json)
- 並列ビルドをサポートする
isolatedDeclarations(TS 5.5+) - Node.js による直接実行向けの
erasableSyntaxOnly(TS 5.8+) - モジュール評価を遅延する
import defer(TS 5.9+) - TypeScript 6.0 の新しいデフォルト設定と非推奨項目
詳細なリソース:
- examples/core.md - 設定例、専用設定、TS 5.x 以降の機能の全容
- reference.md - 判断の枠組み、アンチパターン、注意点
基本理念
TypeScript の設定は、デフォルトで厳格にし、パッケージ間で共有し、将来との互換性を確保する必要があります。すべてのプロジェクトで、最も厳格な設定から始めます。共有設定によって差異の拡大を防ぎます。最新のモジュール設定は、バンドラーベースのワークフローに適合します。
基本原則:
- デフォルトで厳格にする -
strict: trueに加えて、noUncheckedIndexedAccess、exactOptionalPropertyTypes、noImplicitOverrideを設定します - 重複させず、共有する - モノレポの設定は共有ベースを拡張します。単独のプロジェクトでも同じ厳格オプションを使用します
- 最新のモジュールモード - バンドラープロジェクトでは
module: "preserve"とmoduleResolution: "bundler"を使用し、Node.js では"node18"/"node20"を使用します - パスエイリアスの一致 - エイリアスは tsconfig とビルドツールの両方に設定する必要があります
基本パターン
パターン 1:共通の厳格な設定ベース
すべてのアプリとパッケージは、共通の厳格なベース設定を拡張します。ベース設定は packages/typescript-config/(モノレポ)に置くか、単独プロジェクトでは設定を直接記述します。
// packages/typescript-config/base.json (abbreviated)
{
"compilerOptions": {
"strict": true,
"exactOptionalPropertyTypes": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"module": "preserve",
"moduleResolution": "bundler",
"verbatimModuleSyntax": true
}
}
利用側の設定では共通ベースを拡張し、異なる部分(例:paths)だけを追加します。
良い点: 厳格な設定の信頼できる唯一の情報源となり、すべてのパッケージに同じ安全性が適用されます。利用側では異なる部分だけを追加できます。
ベース設定、利用側の設定、特化した設定(react.json、node.json、library.json)の完全な例については、examples/core.md を参照してください。
パターン 2:最新のモジュール設定(TS 5.x+)
verbatimModuleSyntax(TS 5.0+)
型のみをインポートする場合に、明示的な import type を必須にします。非推奨の importsNotUsedAsValues と preserveValueImports に代わる設定です。
// With verbatimModuleSyntax: true
// Good - explicit type import
import type { User } from "./types";
import { createUser } from "./api";
// Bad - type imported as value (errors with verbatimModuleSyntax)
import { User, createUser } from "./api";
module: "preserve"(TS 5.4+)
import/export の構文をそのまま保持します。TypeScript は型チェックのみを行い、モジュールの出力はバンドラーが処理します。
使用する場合: TypeScript が JavaScript を出力しない(noEmit: true)バンドラーベースのプロジェクト
使用しない場合: CJS/ESM を直接出力する Node.js パッケージ。代わりに module: "node18" または "node20" を使用してください。
moduleDetection: "force"(TS 5.0+)
import/export がないファイルも含め、すべてのファイルをモジュールとして扱います。意図しないグローバルスコープの汚染を防ぎます。
パターン 3:${configDir} テンプレート変数(TS 5.5+)
共通設定をポータブルにします。${configDir} はベース設定ではなく、末端の設定(拡張する側の設定)のディレクトリに解決されます。
// packages/typescript-config/base.json
{
"compilerOptions": {
"outDir": "${configDir}/dist",
"rootDir": "${configDir}/src"
},
"include": ["${configDir}/src"]
}
良い点: outDir、rootDir、include を利用側で上書きする必要はありません。パスは利用側のディレクトリを基準に解決されます。
注意点: ${configDir} を使わない場合、"./dist" のような相対パスは利用側のパッケージではなく、ベース設定の場所(packages/typescript-config/)を基準に解決されます。
パターン 4:パスエイリアスの同期
パスエイリアスは、tsconfig.json とビルドツールの両方で設定する必要があります。設定が一致しないと、TypeScript のエラー、またはビルド時のインポート解決エラーが発生します。
// tsconfig.json -- paths here for TypeScript type checking
{ "compilerOptions": { "paths": { "@/*": ["./src/*"] } } }
// Build tool config -- SAME aliases for bundler resolution
// resolve: { alias: { "@": path.resolve(__dirname, "./src") } }
注意点: 同期を忘れると、「module not found」エラーが発生します。TypeScript では正しく解決されても、バンドラーで失敗する(またはその逆)ことがあります。新しいエイリアスを追加する際は、必ず両方のファイルを更新してください。
tsconfig とビルドツールの設定例については、examples/core.md を参照してください。
パターン 5:isolatedDeclarations(TS 5.5+)
すべてのエクスポートに明示的な型注釈を必須にします。外部ツール(oxc、swc)による並列 .d.ts 生成が可能になります。
// With isolatedDeclarations: true
// Good - explicit return type on export
export function getUser(id: string): User {
return { id, name: "John" };
}
// Bad - inferred return type (will error)
export function getUser(id: string) {
return { id, name: "John" };
}
使用する場合: 並列 .d.ts 生成によってビルドを高速化できる、大規模なモノレポでライブラリパッケージを公開する場合
使用しない場合: ライブラリとして使用されないアプリケーションコード(利点がないまま記述が冗長になります)
パターン 6:erasableSyntaxOnly(TS 5.8+)
実行時の動作を伴う TypeScript 固有の構文(enum、namespace、パラメータープロパティ)を禁止します。Node.js の --experimental-strip-types を使った TypeScript の直接実行との互換性を確保します。
禁止される構文: enum、const enum、実行時の namespace、パラメータープロパティ(constructor(public name: string))
使用できる構文: type、interface、型のみのインポートなど、実行時の動作を変えずに消去できるもの
使用する場合: Node.js による TypeScript の直接実行を利用するプロジェクト、または型のみを扱う方針を採用するプロジェクト
使用しない場合: enum、namespace、パラメータープロパティに大きく依存するプロジェクト
良い例・悪い例の完全なコードについては、examples/core.md を参照してください。
パターン 7:import defer(TS 5.9+)
モジュールの評価を遅延します。モジュールは読み込まれますが、エクスポートにアクセスするまで実行されません。--module preserve または esnext の場合に限り、名前空間インポートで動作します。
import * as analytics from "./heavy-analytics.js";
// Module is loaded but NOT executed yet
if (needsAnalytics) {
analytics.track("event"); // Module executes here on first access
}
使用する場合: 条件付きで読み込まれる重いモジュールの起動パフォーマンスを改善する場合
制限事項: import defer では名前付きインポートとデフォルトインポートはサポートされません。名前空間構文(import defer * as ...)のみ使用できます。
パターン 8:TypeScript 6.0 の新しいデフォルト設定
TS 6.0(2026 年 2 月)では、いくつかのデフォルト設定が変更されます。すでに上記のパターンに従って設定している場合、ほとんどの変更は透過的に適用されます。
| オプション | 以前のデフォルト | TS 6.0 のデフォルト |
|---|---|---|
strict | false | true |
module | commonjs | esnext |
target | es3 | es2025 |
rootDir | 推論される | .(現在のディレクトリ) |
types | @types/* を自動検出 | [](明示的に指定されたもののみ) |
noUncheckedSideEffectImports | false | true |
libReplacement | true | false |
対応が必要です: TS 6.0 へのアップグレード後は、"types": ["node"](または関連パッケージ)を明示的に設定してください。@types/* の自動検出は廃止されます。
TS 6.0 で非推奨(TS 7.0 で削除):
target: "es5"、moduleResolution: "node"(node10)、module: "amd"|"umd"|"systemjs"|"none"esModuleInterop: false、モジュール解決ルートとしての--baseUrl、--outFile
移行中は "ignoreDeprecations": "6.0" を使用して、警告を抑制してください。
TS 6.0 のデフォルト設定一覧と非推奨項目の詳細については、examples/core.md を参照してください。
パターン 9:NoInfer ユーティリティ型(TS 5.4 以降)
ジェネリック関数の特定の位置から TypeScript が型を推論するのを防ぎます。
// Good - NoInfer ensures initial must be from states array
declare function createFSM<TState extends string>(config: {
initial: NoInfer<TState>;
states: TState[];
}): void;
createFSM({
initial: "invalid", // Error: "invalid" not in states
states: ["open", "closed"],
});
利点: TypeScript は states のみから TState を推論します。initial はユニオン型を拡張せずに一致する必要があります。
使用する場面: 一方の引数が推論された型を拡張するのではなく、別の引数を制約するジェネリック関数
<decision_framework>
判断フレームワーク
モジュール設定の選択
What module/moduleResolution to use?
├─ Bundler-based project (TypeScript does NOT emit JS)?
│ └─ YES -> module: "preserve", moduleResolution: "bundler"
├─ Node.js package (direct execution)?
│ ├─ Node 20+? -> module: "node20" (TS 5.9+, stable)
│ └─ Node 18+? -> module: "node18" (TS 5.8+)
└─ Library consumed by both bundlers and Node?
└─ module: "nodenext" (most compatible)
ターゲットの選択
What target to use?
├─ Bundler-based project? -> target: "ES2022" (stable, well-supported)
├─ Node.js 18+? -> target: "ES2022"
├─ Node.js 20+? -> target: "ES2023"
└─ TS 6.0+ project? -> target: "es2025" (new default)
新機能の採用
isolatedDeclarations?
├─ Publishing library packages in large monorepo? -> Enable
├─ Application code only? -> Skip (adds verbosity for no benefit)
└─ Using oxc or swc for builds? -> Enable (these tools benefit most)
erasableSyntaxOnly?
├─ Using Node.js --experimental-strip-types? -> Enable (required)
├─ Project uses enums extensively? -> Skip (migration cost too high)
└─ Standard bundler project? -> Optional (nice-to-have)
追加の判断フレームワーク(共有設定とローカル設定の比較、TS 6.0 への移行)については、reference.md を参照してください。
</decision_framework>
<red_flags>
重大な問題
優先度の高い問題:
- TypeScript の strict モード(
strict: false)を無効にしている — プロジェクト全体で暗黙の any や null に関するバグが発生する可能性があります verbatimModuleSyntax: trueが設定されていない — 型のインポートがトランスパイラーによって削除されたり、削除されなかったりします- モノレポで共有設定を使っていない — 設定に差異が生じ、パッケージ間で安全性のレベルが一貫しなくなります
- 非推奨の
importsNotUsedAsValuesまたはpreserveValueImportsを使っている — TS 5.0 以降はverbatimModuleSyntaxに置き換えられています
優先度が中程度の問題:
- tsconfig にパスエイリアスが設定されているものの、ビルドツールには設定されていない(またはその逆) — インポートの解決に失敗します
- 非推奨の
moduleResolution: "node"(node10)を"bundler"または"node18"の代わりに使っている — TS 6.0 で非推奨になりました - 非推奨の
target: "ES3"または"ES5"を使っている — TS 6.0 で非推奨になり、TS 7.0 で削除されます - 共有ベース設定を拡張せず、パッケージごとに設定を重複させている
注意点とエッジケース:
${configDir}はベース設定ではなく、extendsを使用する末端の設定ファイルのディレクトリに解決されますverbatimModuleSyntaxを使う場合、型のみのインポートにはすべてimport typeを使う必要があります —Typeが型のみの場合、import { Type, value }のような混在インポートはエラーになります。インライン構文import { type Type, value }を使ってくださいexactOptionalPropertyTypesを設定すると、{ key?: string }は{ key: undefined }を受け付けません — 許可されるのはプロパティの省略、またはstringの値のみですnoUncheckedIndexedAccessを設定すると、配列を含むすべてのインデックスシグネチャに| undefinedが追加されます —for...ofを使うか、ifでガードしてくださいmodule: "preserve"が機能するのは、noEmit: trueまたはemitDeclarationOnly: trueを設定している場合のみです- TS 6.0 では
typesのデフォルトが[]に変更されます — アップグレード後は@types/nodeや@types/reactなどを明示的に列挙する必要があります import deferがサポートするのは名前空間構文(import defer * as ...)のみで、名前付きインポートやデフォルトインポートには対応していません
</red_flags>
<critical_reminders>
重要な注意事項
(すべての tsconfig.json ファイルで TypeScript の strict モード(strict: true)を有効にする必要があります。これは必須です)
(明示的な import type を徹底するため、verbatimModuleSyntax: true を使う必要があります。これは非推奨の importsNotUsedAsValues に代わるものです)
(モノレポでは共有設定パターン(packages/typescript-config/)を使う必要があります。パッケージごとに設定を重複させてはいけません)
(tsconfig.json とビルドツールのパスエイリアスを同期させる必要があります。不一致があるとインポートの解決に失敗します)
(最新のモジュール設定を使う必要があります。バンドラーを使うプロジェクトでは、module: "preserve" と moduleResolution: "bundler" を設定してください)
これらのルールに従わないと、型安全性の欠落、設定の不整合、インポート解決の失敗につながります。
</critical_reminders>