Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions packages/tsconfig/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# @plainbrew/tsconfig

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

## 使い方

> **TypeScript >= 5.8 が必要です** (`erasableSyntaxOnly` は TS 5.8+、`noUncheckedSideEffectImports` は TS 5.6+)

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

// React
{ "extends": "@plainbrew/tsconfig/react" }
```
Comment on lines +5 to +15
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.


## 設計判断

`@tsconfig/strictest`, `@sindresorhus/tsconfig`, `@total-typescript/tsconfig` 等の大規模 OSS を参考に設計。

### Strict 系

| オプション | 採用理由 |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| [`strict`](https://www.typescriptlang.org/tsconfig/#strict) | `strictNullChecks`, `noImplicitAny` 等を一括有効化 |
| [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig/#exactOptionalPropertyTypes) | `undefined` の明示的な使用を強制。`@tsconfig/strictest` と同方針 |
| [`noFallthroughCasesInSwitch`](https://www.typescriptlang.org/tsconfig/#noFallthroughCasesInSwitch) | switch 文の break 忘れを防止 |
| [`noImplicitOverride`](https://www.typescriptlang.org/tsconfig/#noImplicitOverride) | `override` キーワードの明示を強制し、継承元の変更検知を容易に |
| [`noImplicitReturns`](https://www.typescriptlang.org/tsconfig/#noImplicitReturns) | 全コードパスでの return を強制 |
| [`noPropertyAccessFromIndexSignature`](https://www.typescriptlang.org/tsconfig/#noPropertyAccessFromIndexSignature) | index signature へのドットアクセスを禁止し、bracket notation を強制 |
| [`noUncheckedIndexedAccess`](https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess) | 配列・オブジェクトのインデックスアクセスに `undefined` を含める |
| [`noUncheckedSideEffectImports`](https://www.typescriptlang.org/tsconfig/#noUncheckedSideEffectImports) | `import "./styles.css"` 等の副作用 import の存在チェック (TS 5.6+)。`@sindresorhus/tsconfig` が採用 |
| [`noUnusedLocals`](https://www.typescriptlang.org/tsconfig/#noUnusedLocals) / [`noUnusedParameters`](https://www.typescriptlang.org/tsconfig/#noUnusedParameters) | 未使用変数・引数を検出 |
| [`allowUnusedLabels`](https://www.typescriptlang.org/tsconfig/#allowUnusedLabels) / [`allowUnreachableCode`](https://www.typescriptlang.org/tsconfig/#allowUnreachableCode) | `false` に設定。到達不能コードや未使用ラベルをエラーに |
| [`erasableSyntaxOnly`](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) | `enum`, `namespace` 等の型消去不可能な構文を禁止 (TS 5.8+)。Node.js の `--experimental-strip-types` と互換。`@sindresorhus/tsconfig` が採用 |

### Module 系

| オプション | 採用理由 |
| -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| [`module`](https://www.typescriptlang.org/tsconfig/#module): `"preserve"` | import/export をそのまま保持しバンドラーに委ねる (TS 5.4+) |
| [`moduleResolution`](https://www.typescriptlang.org/tsconfig/#moduleResolution): `"bundler"` | Vite, webpack, Next.js 等のバンドラー環境に最適化 |
| [`moduleDetection`](https://www.typescriptlang.org/tsconfig/#moduleDetection): `"force"` | 全ファイルをモジュールとして扱いグローバルスコープ汚染を防止。`@total-typescript/tsconfig`, `@sindresorhus/tsconfig` が採用 |
| [`isolatedModules`](https://www.typescriptlang.org/tsconfig/#isolatedModules) | ファイル単位のトランスパイルを保証。esbuild, SWC 等との互換性確保 |
| [`esModuleInterop`](https://www.typescriptlang.org/tsconfig/#esModuleInterop) | CJS モジュールの default import を安全に扱う。`verbatimModuleSyntax` は CJS 環境で問題があるため不採用(ESLint ルールで代替) |
| [`resolveJsonModule`](https://www.typescriptlang.org/tsconfig/#resolveJsonModule) | JSON ファイルの型安全な import を許可 |
| [`skipLibCheck`](https://www.typescriptlang.org/tsconfig/#skipLibCheck) | `.d.ts` のチェックをスキップしビルド高速化。ほぼ全ての主要パッケージが採用 |

### 意図的に含めないオプション

| オプション | 不採用理由 |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [`target`](https://www.typescriptlang.org/tsconfig/#target) / [`lib`](https://www.typescriptlang.org/tsconfig/#lib) | 実行環境に依存するため拡張先に委ねる |
| [`declaration`](https://www.typescriptlang.org/tsconfig/#declaration) / [`declarationMap`](https://www.typescriptlang.org/tsconfig/#declarationMap) / [`sourceMap`](https://www.typescriptlang.org/tsconfig/#sourceMap) | output 系は strictness と無関係。app と library で要件が異なる |
| [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) | CJS 出力環境で `import` を `require()` に変換不可。ESLint (`@typescript-eslint/consistent-type-imports`) で代替可能 |
| [`forceConsistentCasingInFileNames`](https://www.typescriptlang.org/tsconfig/#forceConsistentCasingInFileNames) | TS 5.0 以降デフォルト `true` |
| [`noEmit`](https://www.typescriptlang.org/tsconfig/#noEmit) | バンドラー/フレームワーク設定に依存 |

### React 設定 (`react.json`)

ベースを継承し、React 固有のオプションのみ追加:

- [`jsx`](https://www.typescriptlang.org/tsconfig/#jsx): `"react-jsx"` — React 17+ の JSX Transform を使用
- [`lib`](https://www.typescriptlang.org/tsconfig/#lib): `["dom", "dom.iterable", "esnext"]` — ブラウザ API の型定義
24 changes: 24 additions & 0 deletions packages/tsconfig/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@plainbrew/tsconfig",
"version": "0.1.0",
"description": "Strict TypeScript configuration for plainbrew projects",
"keywords": [
"react",
"strict",
"tsconfig",
"typescript"
],
"license": "MIT",
"files": [
"tsconfig.json",
"react.json"
],
"type": "module",
"exports": {
".": "./tsconfig.json",
"./react": "./react.json"
},
"peerDependencies": {
"typescript": ">=5.8.0"
}
}
8 changes: 8 additions & 0 deletions packages/tsconfig/react.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx",
"lib": ["dom", "dom.iterable", "esnext"]
}
}
25 changes: 25 additions & 0 deletions packages/tsconfig/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"strict": true,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,
"noUncheckedSideEffectImports": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowUnusedLabels": false,
"allowUnreachableCode": false,
"erasableSyntaxOnly": true,
"isolatedModules": 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

は〜〜

"skipLibCheck": true,
"moduleDetection": "force",
"moduleResolution": "bundler",
"module": "preserve",
"resolveJsonModule": true
}
}
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packages:
- "packages/*"