Skip to content

strict な tsconfig パッケージの作成#9

Open
akameco wants to merge 10 commits intoplainbrew:mainfrom
akameco:create-strict-tsconfig-package
Open

strict な tsconfig パッケージの作成#9
akameco wants to merge 10 commits intoplainbrew:mainfrom
akameco:create-strict-tsconfig-package

Conversation

@akameco
Copy link

@akameco akameco commented Feb 26, 2026

概要

fix #6

strict な TypeScript 設定を共有パッケージ @plainbrew/tsconfig として提供します。

変更内容

  • pnpm workspaces の設定を追加
  • @plainbrew/tsconfig パッケージの作成
    • ベース設定 (@plainbrew/tsconfig): 厳格な型チェックオプションを網羅
    • React 設定 (@plainbrew/tsconfig/react): JSX と DOM lib を追加した React 向け設定
  • 各オプションの採用理由・不採用理由を README に記載(大規模 OSS を参考)

使用方法

// ベース
{ "extends": "@plainbrew/tsconfig" }

// React
{ "extends": "@plainbrew/tsconfig/react" }

含まれる strict 設定

  • strict: true
  • exactOptionalPropertyTypes
  • noUncheckedIndexedAccess
  • noUncheckedSideEffectImports (TS 5.6+)
  • noPropertyAccessFromIndexSignature
  • noImplicitOverride
  • noImplicitReturns
  • noFallthroughCasesInSwitch
  • noUnusedLocals / noUnusedParameters
  • allowUnusedLabels: false / allowUnreachableCode: false
  • erasableSyntaxOnly (TS 5.8+)
  • isolatedModules
  • moduleDetection: "force"
  • moduleResolution: "bundler" / module: "preserve"

設計判断ドキュメント

packages/tsconfig/README.md に各オプションの採用理由を記載。@tsconfig/strictest, @sindresorhus/tsconfig, @total-typescript/tsconfig 等を参考に設計。

動作確認方法

  • pnpm run format:check がパスすること
  • 別プロジェクトで extends して TypeScript の strict チェックが有効になること

Summary by CodeRabbit

リリースノート

  • New Features

    • 共有可能な TypeScript 設定パッケージを追加しました。厳密な型チェックや安全性チェックを有効にした基本設定と、React 用の拡張設定を提供します。
  • Documentation

    • パッケージの導入手順、使用例、設計方針や設定の意図を説明するドキュメントを追加しました。

packages/* をワークスペースとして管理するための設定を追加
strict な TypeScript 設定を共有パッケージとして提供
- ベース設定: 厳格な型チェックオプションを網羅
- React 設定: JSX と DOM lib を追加した React 向け設定
@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

plainbrew向けの厳格な TypeScript 設定を提供する新パッケージ @plainbrew/tsconfig を追加しました。tsconfig.jsonreact.jsonpackage.json、READMEを含み、pnpmワークスペースに packages/* を追加しています。

Changes

Cohort / File(s) Summary
TypeScript 設定パッケージ
packages/tsconfig/package.json, packages/tsconfig/tsconfig.json, packages/tsconfig/react.json, packages/tsconfig/README.md
新規パッケージ @plainbrew/tsconfig を追加。厳格なコンパイラオプションを定義した tsconfig.json、React向け拡張の react.json、それらをエクスポートする package.jsontypescript を peerDependency)と使用ドキュメントを追加。
ワークスペース設定
pnpm-workspace.yaml
pnpm ワークスペース設定を追加し、packages/* をワークスペースに含めるようにした。

Sequence Diagram(s)

(該当なし)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 新しき設定、芽吹けり
厳格な型でぴょんと跳ねて
React と共に空へ飛ぶ
小さな package が道をひらき
ビルドの朝、軽やかに始まる

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトルは、厳密な TypeScript 設定パッケージの作成というこの変更セットの主要な目的を正確に反映しており、明確です。
Linked Issues check ✅ Passed プルリクエストは Issue #6 のすべてのコード関連要件を満たしています。strict な tsconfig.json、React 設定、README ドキュメント、pnpm ワークスペース設定が含まれています。
Out of Scope Changes check ✅ Passed すべての変更は Issue #6 で定義されたスコープ内で、strict な tsconfig パッケージの作成に直接関連しています。スコープ外の変更は検出されていません。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@akameco akameco marked this pull request as ready for review February 26, 2026 03:51
"allowUnreachableCode": false,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"esModuleInterop": true,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claudeより: verbatimModuleSyntax と esModuleInterop の併用は冗長。verbatimModuleSyntax: true を採用しているなら esModuleInteropは削除を検討。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これら問題は、verbatimModuleSyntaxを有効化しなくても、ESLint で@typescript-eslint/consistent-type-imports と @typescript-eslint/no-import-type-side-effects を有効化することでほとんど解決できる。auto-fix も効くし、どの環境でも特にデメリットはない?と思うのでとりあえずこれらを有効化しておくのが良さそう。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next.js は SWC を使用して構文を最適化するため、このオプションを true にして構文をそのまま渡すことが推奨されます。
https://zenn.dev/hayato94087/books/b174f8b1cd80db/viewer/v00-05-16-kj8s5o8gppf5#next.js-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E8%A8%AD%E5%AE%9A

は〜〜

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/tsconfig/tsconfig.json (1)

20-25: shareable基本設定から出力関連オプションを分離してください。

@plainbrew/tsconfigは他プロジェクトに継承される基本設定です。moduleResolution: "bundler"declarationの組み合わせは、Node.js ESM環境での互換性問題を引き起こす可能性があります。bundler解決戦略は拡張子なしのインポート(export * from "./utils")を許可しますが、生成される.d.tsファイルはNode.jsコンシューマーで無効になります。

出力戦略(declarationdeclarationMapsourceMap)はプロジェクトの用途(アプリ vs ライブラリ)に応じて異なるため、基本設定では削除し、各プロジェクトで明示的に設定させることを推奨します。

♻️ 提案差分
   "compilerOptions": {
@@
-    "resolveJsonModule": true,
-    "declaration": true,
-    "declarationMap": true,
-    "sourceMap": true
+    "resolveJsonModule": true
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/tsconfig/tsconfig.json` around lines 20 - 25, The shared tsconfig
currently mixes moduleResolution: "bundler" and output-related flags
(declaration, declarationMap, sourceMap) into the base config which can break
Node ESM consumers; remove the output flags (declaration, declarationMap,
sourceMap) from the base `@plainbrew/tsconfig` and keep only resolution and module
semantics, so projects must opt-in to declarations and source maps in their own
tsconfig overrides; specifically remove "declaration", "declarationMap", and
"sourceMap" entries and document that projects should set these per-package
while leaving "moduleResolution" and "module" as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/tsconfig/package.json`:
- Around line 1-21: Add a peerDependencies entry to the package.json of the
`@plainbrew/tsconfig` package declaring a minimum TypeScript version to prevent
consumers with older compilers from failing; specifically add a
"peerDependencies" object with "typescript": ">=5.4.0" (since tsconfig.json uses
"module": "preserve" and other options like "moduleResolution": "bundler" that
require TS >=5.4.0) so package consumers are informed of the required TypeScript
version.

---

Nitpick comments:
In `@packages/tsconfig/tsconfig.json`:
- Around line 20-25: The shared tsconfig currently mixes moduleResolution:
"bundler" and output-related flags (declaration, declarationMap, sourceMap) into
the base config which can break Node ESM consumers; remove the output flags
(declaration, declarationMap, sourceMap) from the base `@plainbrew/tsconfig` and
keep only resolution and module semantics, so projects must opt-in to
declarations and source maps in their own tsconfig overrides; specifically
remove "declaration", "declarationMap", and "sourceMap" entries and document
that projects should set these per-package while leaving "moduleResolution" and
"module" as-is.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f11132b and 911e03a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/tsconfig/package.json
  • packages/tsconfig/react.json
  • packages/tsconfig/tsconfig.json
  • pnpm-workspace.yaml

CJS 環境との互換性問題があるため削除。
型 import の強制は ESLint ルールで対応する方が安全。
ref: https://zenn.dev/teppeis/articles/2023-04-typescript-5_0-verbatim-module-syntax
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/tsconfig/tsconfig.json (1)

19-20: moduleResolution: "bundler"module: "preserve" はベース設定としては強すぎます。

Line [19]〜Line [20] は環境依存のため、ベース (@plainbrew/tsconfig) では外し、必要な派生設定(例: ./react)側で付与する構成の方が再利用性が高いです。

差分案
-    "moduleResolution": "bundler",
-    "module": "preserve",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/tsconfig/tsconfig.json` around lines 19 - 20, ベース tsconfig にある設定キー
"moduleResolution": "bundler" と "module": "preserve"
は環境依存で強すぎるため、ベース設定からこれらのキーを削除して再利用性を高めてください;代わりに、React 等の派生構成ファイル(例: a derived
tsconfig for React)で "moduleResolution" と "module"
を必要に応じて明示的に追加するように変更し、既存の参照先やビルドスクリプトが新しい派生ファイルを使うように更新してください。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/tsconfig/tsconfig.json`:
- Around line 22-24: Remove the emit-related compiler options from the base
config: delete "declaration", "declarationMap", and "sourceMap" from the
tsconfig JSON so the `@plainbrew/tsconfig` package no longer forces emit behavior
on consumers; leave strict/type-checking settings intact and update any README
or docs to instruct library projects to enable these emit options (or set
noEmit) in their own tsconfig overrides.

---

Nitpick comments:
In `@packages/tsconfig/tsconfig.json`:
- Around line 19-20: ベース tsconfig にある設定キー "moduleResolution": "bundler" と
"module": "preserve" は環境依存で強すぎるため、ベース設定からこれらのキーを削除して再利用性を高めてください;代わりに、React
等の派生構成ファイル(例: a derived tsconfig for React)で "moduleResolution" と "module"
を必要に応じて明示的に追加するように変更し、既存の参照先やビルドスクリプトが新しい派生ファイルを使うように更新してください。

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 911e03a and 69e1d85.

📒 Files selected for processing (1)
  • packages/tsconfig/tsconfig.json

大規模 OSS (@tsconfig/strictest, @sindresorhus/tsconfig, @total-typescript/tsconfig) との
比較レビューに基づく改善:

- add: noUncheckedSideEffectImports (TS 5.6+, 副作用 import の存在チェック)
- add: erasableSyntaxOnly (TS 5.8+, enum/namespace を禁止)
- add: moduleDetection: "force" (全ファイルをモジュールとして扱う)
- remove: declaration, declarationMap, sourceMap (output 系は拡張先に委ねる)
- remove: forceConsistentCasingInFileNames (TS 5.0 以降デフォルト true)
各オプションの採用理由と不採用理由を OSS の参考元とともに記載
各オプションに公式ドキュメントへのリンクを追加
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/tsconfig/README.md`:
- Around line 5-13: Add a clear TypeScript minimum version note at the top of
the README usage section stating that this config requires TypeScript >=5.8
(because erasableSyntaxOnly needs TS 5.8 and noUncheckedSideEffectImports needs
TS 5.6), and update package.json peerDependencies entry for "typescript" from
">=5.4.0" to ">=5.8.0"; specifically edit the README usage block near the top
(the usage examples around the extends lines) to include the version requirement
and change the peerDependencies in package.json to reflect the new minimum.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69e1d85 and 92a5a8a.

📒 Files selected for processing (3)
  • packages/tsconfig/README.md
  • packages/tsconfig/package.json
  • packages/tsconfig/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/tsconfig/tsconfig.json
  • packages/tsconfig/package.json

Comment on lines +5 to +13
## 使い方

```jsonc
// ベース
{ "extends": "@plainbrew/tsconfig" }

// React
{ "extends": "@plainbrew/tsconfig/react" }
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

TypeScript erasableSyntaxOnly compiler option introduced version

💡 Result:

The --erasableSyntaxOnly compiler option was introduced in TypeScript 5.8 (first available in the 5.8 Beta released January 29, 2025). [1] It’s also documented in the TypeScript 5.8 release notes. [2]

Sources:
[1] TypeScript 5.8 Beta announcement (Jan 29, 2025)
[2] TypeScript 5.8 release notes


🌐 Web query:

TypeScript noUncheckedSideEffectImports compiler option introduced version

💡 Result:

The noUncheckedSideEffectImports compiler option was introduced in TypeScript 5.6. [1]

Sources:
[1] TypeScript blog – Announcing TypeScript 5.6 (section “The --noUncheckedSideEffectImports Option”) https://devblogs.microsoft.com/typescript/announcing-typescript-5-6/


🏁 Script executed:

# Check the actual README file content
cat packages/tsconfig/README.md

Repository: plainbrew/configs

Length of output: 8748


🏁 Script executed:

# Check the tsconfig configurations being used
find packages/tsconfig -name "*.json" -type f | head -20

Repository: plainbrew/configs

Length of output: 152


🏁 Script executed:

# Check package.json to see peerDependencies
cat packages/tsconfig/package.json 2>/dev/null || echo "File not found"

Repository: plainbrew/configs

Length of output: 505


TypeScript の最小要件を冒頭で明示し、peerDependencies も修正してください。

設計判断テーブル(Line 30 / Line 33)の通り、erasableSyntaxOnly は TS 5.8+、noUncheckedSideEffectImports は TS 5.6+ が必須です。現状では使い方セクション(Lines 5-13)に版要件がないため、TS 5.4~5.7 のユーザーが extends 後に unknown compiler option エラーに直面します。

併せて、package.jsonpeerDependenciestypescript: >=5.4.0 から typescript: >=5.8.0 に修正してください。

✍️ 提案差分(README 追記)
 # `@plainbrew/tsconfig`

 plainbrew プロジェクト向けの strict な TypeScript 設定。

+## 必要要件
+
+- TypeScript: `>= 5.8`(`erasableSyntaxOnly` を利用するため)
+  - `noUncheckedSideEffectImports` は TypeScript 5.6+ が必要です
+
 ## 使い方
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## 使い方
```jsonc
// ベース
{ "extends": "@plainbrew/tsconfig" }
// React
{ "extends": "@plainbrew/tsconfig/react" }
```
## 必要要件
- TypeScript: `>= 5.8``erasableSyntaxOnly` を利用するため)
- `noUncheckedSideEffectImports` は TypeScript 5.6+ が必要です
## 使い方
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/tsconfig/README.md` around lines 5 - 13, Add a clear TypeScript
minimum version note at the top of the README usage section stating that this
config requires TypeScript >=5.8 (because erasableSyntaxOnly needs TS 5.8 and
noUncheckedSideEffectImports needs TS 5.6), and update package.json
peerDependencies entry for "typescript" from ">=5.4.0" to ">=5.8.0";
specifically edit the README usage block near the top (the usage examples around
the extends lines) to include the version requirement and change the
peerDependencies in package.json to reflect the new minimum.

Update peerDependencies minimum from >=5.4.0 to >=5.8.0 and add
version requirement note to README usage section.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/tsconfig/package.json`:
- Around line 21-23: The CI failure is caused by a mismatch between
peerDependencies.typescript in package.json (now ">=5.8.0") and the specifier
recorded in pnpm-lock.yaml (still ">=5.4.0"); fix it by running the repository
root command `pnpm install` to regenerate pnpm-lock.yaml so its specifiers match
package.json, then commit the updated pnpm-lock.yaml alongside your package.json
change.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92a5a8a and f3e671f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • packages/tsconfig/README.md
  • packages/tsconfig/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/tsconfig/README.md

@akameco
Copy link
Author

akameco commented Feb 27, 2026

🤖 Claude's Review: @tsconfig/strictest をベースにするか?

@tsconfig/strictest v2.0.0 と本パッケージを比較しました。

結論: 現状のスタンドアロン構成を維持する方が良い

比較結果

@tsconfig/strictest のオプション(14個)はすべて本パッケージに含まれています。
本パッケージにのみ存在するオプションは以下の6個です:

オプション 説明
noUncheckedSideEffectImports true 副作用importのチェック (TS 5.6+)
erasableSyntaxOnly true enum/namespace禁止 (TS 5.8+)
moduleDetection "force" 全ファイルをモジュール化
moduleResolution "bundler" バンドラー向け解決
module "preserve" import/exportをそのまま保持
resolveJsonModule true JSON importの型安全化

スタンドアロンを推す理由

  1. 追従の遅さ: @tsconfig/strictestnoUncheckedSideEffectImports (TS 5.6) や erasableSyntaxOnly (TS 5.8) といった最新オプションを未収録。自前管理の方が最新追従しやすい
  2. 可視性: 全20個のオプションが1ファイルで見渡せる。extends すると暗黙の設定が生まれる
  3. 依存ゼロ: strict設定という基盤に外部依存を持ち込むリスクを回避
  4. 管理コストの低さ: オプション数が少なく、TypeScriptのリリースノートで差分確認すれば十分

仮に extends する場合でも、追加の6オプションを上書きする必要があり、メリットが薄いです。


このコメントは Claude (AI) によるレビューです

@akameco
Copy link
Author

akameco commented Feb 27, 2026

🤖 Claude's Follow-up: @tsconfig/strictest をベースにするメリット

前のコメントではスタンドアロンを推しましたが、extends するアプローチにも明確なメリットがあります。

ベースにする場合のメリット

  • メンテナンス負荷の軽減 - strict 系オプションの追従をコミュニティに委ねられる。新しい strict オプションが追加されても自動で取り込まれる
  • 差分だけ管理 - @plainbrew/tsconfig は bundler 向け設定(moduleResolution: "bundler" 等)と最新オプション(erasableSyntaxOnly 等)を追加するだけで済む
  • 依存関係が明確 - 「strictest + bundler」という構成意図が一目でわかる

extends した場合のイメージ

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@tsconfig/strictest/tsconfig.json",
  "compilerOptions": {
    "noUncheckedSideEffectImports": true,
    "erasableSyntaxOnly": true,
    "moduleDetection": "force",
    "moduleResolution": "bundler",
    "module": "preserve",
    "resolveJsonModule": true
  }
}

設定ファイルがシンプルになり、「何を追加しているか」が明確になります。前のコメントで挙げた懸念(追従の遅さ等)は、上書きで対処できるため大きな問題にはなりません。


このコメントは Claude (AI) によるレビューです

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

strict な tsconfig パッケージの作成

1 participant