Skip to content

tsconfig.app.json のオプションを強化#189

Merged
kitsne241 merged 14 commits intomainfrom
feat/add-tsconfig-options
Feb 14, 2026
Merged

tsconfig.app.json のオプションを強化#189
kitsne241 merged 14 commits intomainfrom
feat/add-tsconfig-options

Conversation

@kitsne241
Copy link
Copy Markdown
Collaborator

@kitsne241 kitsne241 commented Jan 10, 2026

#188 の作業中に本来エラーになるべき場所がエラーになっていないような感じがしたので、tsconfig.app.json にいくつかの設定を加えてさらに型チェックを厳しくすることを提案します

核となる制限は "noUncheckedIndexedAccess": true であり、配列外参照が undefined となる仕様を型解釈に取り入れます


追記:このままだとビルドが落ちていてずっと main にマージすることができないので、
#188 がマージされ次第 main をマージしてきて必要なコードの修正を行うことによりビルドを通す予定です

Summary by CodeRabbit

リリースノート

  • チョア

    • 開発環境のTypeScript関連を更新(TypeScript版アップグレード、関連パッケージ追加)
    • エディタ設定でローカルのTypeScriptを使用するよう追加
    • ESLintの未使用変数ルールを調整(警告化・特定パターンを無視)
  • リファクター

    • 型チェックを強化するコンパイラ設定を導入(strict 等)
    • 非nullアサーションや防御的初期化で内部処理の堅牢性を向上
  • 破壊的変更

    • 一部の環境型定義を削除(公開型が減少)

@kitsne241 kitsne241 requested review from Copilot and mumumu6 January 10, 2026 13:20
@github-actions
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances TypeScript configuration with stricter type checking options to improve code safety. The key change is enabling noUncheckedIndexedAccess to handle array element access that may return undefined, along with other strict compiler options. The PR also updates TypeScript and typescript-eslint dependencies and adjusts ESLint rules for better unused variable detection.

Changes:

  • Enhanced tsconfig.app.json with stricter type checking options (noUncheckedIndexedAccess, noUnusedLocals, strict mode)
  • Updated TypeScript version and added typescript-eslint package
  • Configured ESLint rule for unused variables with underscore prefix support

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tsconfig.app.json Added strict type checking options including noUncheckedIndexedAccess, changed lib to ESNext, added vite/client types, removed env.d.ts from includes
package.json Downgraded TypeScript to 5.9.3, added typescript-eslint 8.52.0
package-lock.json Updated dependency versions to match package.json changes
eslint.config.js Added @typescript-eslint/no-unused-vars rule configuration with underscore prefix support
env.d.ts Removed file containing custom environment variable type definitions
.vscode/settings.json Added TypeScript SDK path configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tsconfig.app.json Outdated
Comment on lines +7 to +8
"types": ["vite/client"],
// 環境変数 import.meta.env や静的アセットの型定義を宣言
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

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

The removal of env.d.ts (which previously defined ImportMetaEnv with VITE_CHANNEL_PATH) means custom environment variables are no longer typed. While "types": ["vite/client"] provides base import.meta.env types, it doesn't include project-specific environment variables like VITE_CHANNEL_PATH (used in src/views/RollCallView.vue). Consider creating a vite-env.d.ts or similar file to declare these custom types, or restore the env.d.ts file with its type definitions.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

おっしゃる通り import.meta.env.VITE_CHANNEL_PATH はこの変更に伴い string 型から any 型になりました。好ましくない変化ではありますが致し方ないように思います
環境変数の例を .env などにかき、その型を env.d.ts にかくという運用は保守性に難があります。必要な環境変数が増えたとき、.env の更新自体はされても env.d.ts の型の更新は忘れられがちになるでしょうから、いっそ env.d.ts ごと消して any 型を前提とした運用にするのがよいと考えました。既存の VITE_CHANNEL_PATH の出現箇所は any のままでもエラー等を生じていないようです。この先環境変数が増えたら zod などのライブラリを利用することを視野に入れていますが、今はほとんど VITE_CHANNEL_PATH だけなのでそこまでしなくてもよいかと思っています

Comment thread tsconfig.app.json Outdated

"strict": true,
"noUnusedLocals": true,
"erasableSyntaxOnly": true,
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

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

The erasableSyntaxOnly compiler option is not a valid TypeScript compiler option. This option does not exist in the TypeScript compiler. You may have meant a different option, or this should be removed. Valid related options include isolatedModules or verbatimModuleSyntax.

Suggested change
"erasableSyntaxOnly": true,

Copilot uses AI. Check for mistakes.
@kitsne241 kitsne241 requested a review from mumumu6 January 24, 2026 14:21
@kitsne241
Copy link
Copy Markdown
Collaborator Author

いくつかのリファクタリングを行いビルドを通しました
ロジック上安全であると判断してアサーションを用いた部分が複数箇所あります

mumumu6
mumumu6 previously approved these changes Feb 12, 2026
Copy link
Copy Markdown
Member

@mumumu6 mumumu6 left a comment

Choose a reason for hiding this comment

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

良さそうです!

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 13, 2026

📝 Walkthrough

Walkthrough

TypeScript 設定を厳格化し、ESLint ルールと依存を更新。複数コンポーネント/ユーティリティに非 null アサーションや防御的初期化を追加し、環境型定義を削除、VSCode でローカル TypeScript を使う設定を追加しました。

Changes

Cohort / File(s) Summary
TypeScript / VSCode 設定
tsconfig.app.json, .vscode/settings.json
コンパイラを strict 化(noUncheckedIndexedAccess 等追加)、lib を ESNext に変更。VSCode 設定にローカル TypeScript ("typescript.tsdk": "node_modules/typescript/lib") を追加。
ESLint と依存関係
eslint.config.js, package.json
@typescript-eslint/no-unused-vars を warn で追加(ignorePattern ^_ 等のオプション)。devDependency で typescript~5.9.3 に更新し、typescript-eslint を追加。
イベント関連コンポーネント
src/components/event/EventEditor.vue, src/components/event/EventTimePick.vue, src/components/event/utils/eventGrid.ts
ランダム色選択や timePick の代入に堅牢化(nullish / 非 null アサーション)。eventGrid.ts は行アクセスにランタイムガードと一時変数化、非 null アサーションを導入しフォーマット/エクスポート周りを安全化。
質問/回答関連コンポーネント
src/components/information/AnswersDialog.vue, src/components/information/QuestionGroupEditor.vue, src/components/information/QuestionGroupPanel.vue
byAnsweranswersMap へのアクセスで防御的初期化(??=)や非 null アサーションを追加。ループや配列アクセスの順序・パターンを整理。テンプレートの update バインディングも非 null を仮定。
その他ユーティリティ/型定義
src/components/markdown/utils/editorParse.ts, src/env.d.ts, src/store.ts
editorParse.ts// @ts-nocheck`` を追加。src/env.d.ts から `ImportMetaEnv` / `ImportMeta` 宣言を削除。`store.ts` の初期化で非 null アサーションを追加。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • mumumu6
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR タイトルはメインの変更(tsconfig.app.json の TypeScript コンパイラオプション強化)を正確に反映している。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-tsconfig-options

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/components/event/utils/eventGrid.ts (1)

128-131: addMomentEvent と同様に、インデックスの検証を追加することを検討してください。

getLastIndexgetIndex-1 を返した場合、slice(-1, endIndex)slice(startIndex, -1) は予期しない範囲を返します。addMomentEvent には同様のガードが追加されていますが、こちらには存在しません。

♻️ 修正案
  addDurationEvent(event: DurationEvent | OfficialEvent) {
    const startIndex = this.getLastIndex(getStartTime(event))
    const endIndex = this.getIndex(getEndTime(event))
+   if (startIndex === -1 || endIndex === -1) {
+     throw new Error(`${event.name} の時刻範囲に対応するグリッド行が見つかりません`)
+   }
    const targetRows = this.rows.slice(startIndex, endIndex)

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

Copy link
Copy Markdown

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/event/utils/eventGrid.ts (1)

66-73: ⚠️ Potential issue | 🔴 Critical

previous が未定義です - ランタイムエラーが発生します

Line 68 で previous.time を参照していますが、previous はこのスコープ(1つ目のループ)では定義されていません。previous は Line 82 の2つ目のループでのみ定義されています。

この条件分岐に入ると ReferenceError: previous is not defined が発生します。

🐛 修正案
      if (this.rows[i - 1].events.length === 1 && this.rows[i].events.length === 0) {
        this.rows.splice(i, 0, {
-          time: new Date(previous.time),
+          time: new Date(this.rows[i - 1]!.time),
          events: [],
          minHeight: 'narrow',
          stampAlign: 'none',
        })
      }
🤖 Fix all issues with AI agents
In `@src/components/event/EventEditor.vue`:
- Line 114: The current initialization sets color.value =
EVENT_COLORS[Math.floor(Math.random() * EVENT_COLORS.length)]! which can yield
undefined if EVENT_COLORS is empty; update the logic around EVENT_COLORS and
color.value (the random color assignment) to guard against an empty array by
providing a fallback (e.g., a default color constant) or an explicit check that
sets color.value to the fallback when EVENT_COLORS.length === 0, ensuring no
non-null assertion is relied upon.

In `@src/components/information/AnswersDialog.vue`:
- Line 31:
byAnswer[...]アクセスで非null断言(!)して直接pushしているため、キーが未初期化だとクラッシュします。AnswersDialog.vue内の
byAnswer[answer.selectedOption.content]!.push(answer.userId) と同様に使っている箇所(該当は
lines 31, 40, 49, 57 相当)で、push の前に byAnswer[answer.selectedOption.content] ??=
[] を使って配列を確実に初期化してから answer.userId を push するように修正してください;対象となる識別子は
byAnswer、answer.selectedOption.content、answer.userId です。
🧹 Nitpick comments (1)
src/components/information/QuestionGroupEditor.vue (1)

41-41: QuestionGroupViewer.vue との一貫性を保つため、オプショナルチェーンを使用してください。

answersMap は親コンポーネント (QuestionGroupPanel) で全問題について初期化されるため、現在のコードは技術的には安全です。ただし、読み取り専用の QuestionGroupViewer.vue では answersMap[question.id]?.value とオプショナルチェーンが使われており、エディタコンポーネントでも一貫性を持たせることが望ましいです。非null アサーション ! をオプショナルチェーン ?. に変更することで、より防御的で堅牢なコードになります。

推奨される変更
-    get: () => props.answersMap[questionId]!.value,
+    get: () => props.answersMap[questionId]?.value,

Comment thread src/components/event/EventEditor.vue Outdated
} else {
organizerId.value = userStore.user.id
color.value = EVENT_COLORS[Math.floor(Math.random() * EVENT_COLORS.length)] // 色をランダムで初期化
color.value = EVENT_COLORS[Math.floor(Math.random() * EVENT_COLORS.length)]! // 色をランダムで初期化
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

EVENT_COLORS が空のときに undefined になります。

非nullアサーションで型は通りますが、配列が空なら colorundefined になり得ます。最低限フォールバックか明示的なガードを入れておくと安心です。

✅ 例: フォールバックを追加
-    color.value = EVENT_COLORS[Math.floor(Math.random() * EVENT_COLORS.length)]! // 色をランダムで初期化
+    const randomColor = EVENT_COLORS[Math.floor(Math.random() * EVENT_COLORS.length)]
+    color.value = randomColor ?? color.value // 空配列時は既定値を維持
📝 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
color.value = EVENT_COLORS[Math.floor(Math.random() * EVENT_COLORS.length)]! // 色をランダムで初期化
const randomColor = EVENT_COLORS[Math.floor(Math.random() * EVENT_COLORS.length)]
color.value = randomColor ?? color.value // 空配列時は既定値を維持
🤖 Prompt for AI Agents
In `@src/components/event/EventEditor.vue` at line 114, The current initialization
sets color.value = EVENT_COLORS[Math.floor(Math.random() *
EVENT_COLORS.length)]! which can yield undefined if EVENT_COLORS is empty;
update the logic around EVENT_COLORS and color.value (the random color
assignment) to guard against an empty array by providing a fallback (e.g., a
default color constant) or an explicit check that sets color.value to the
fallback when EVENT_COLORS.length === 0, ensuring no non-null assertion is
relied upon.

Comment thread src/components/information/AnswersDialog.vue
Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@src/components/event/utils/eventGrid.ts`:
- Around line 113-116: In addMomentEvent, guard against getIndex returning -1
before indexing this.rows: assign const idx =
this.getIndex(getStartTime(event)); if idx is -1 either create/append a new row
at the appropriate position or early-return (choose consistent behavior with
addDurationEvent) instead of doing this.rows[idx]!, and then use this.rows[idx]
to push the moment event; update any downstream code that assumes a row exists
so you don't dereference undefined.

Comment thread src/components/event/utils/eventGrid.ts
@kitsne241
Copy link
Copy Markdown
Collaborator Author

コンフリクトが生じていたので main のマージと、ついでに安全処理を行いました
再度レビューお願いしたいです…!

@kitsne241 kitsne241 requested a review from mumumu6 February 14, 2026 01:04
Copy link
Copy Markdown
Member

@mumumu6 mumumu6 left a comment

Choose a reason for hiding this comment

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

良さそうです!ありがとうございます!

@kitsne241 kitsne241 merged commit 474a8a6 into main Feb 14, 2026
5 checks passed
@kitsne241 kitsne241 deleted the feat/add-tsconfig-options branch February 14, 2026 07:28
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.

3 participants