Skip to content

fix(typecheck): add proper type parameters to useState(null) hooks#1513

Merged
kevincodex1 merged 1 commit into
Gitlawb:mainfrom
chioarub:pr-usestate-null
Jun 9, 2026
Merged

fix(typecheck): add proper type parameters to useState(null) hooks#1513
kevincodex1 merged 1 commit into
Gitlawb:mainfrom
chioarub:pr-usestate-null

Conversation

@chioarub

@chioarub chioarub commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Refs #1486.

Adds explicit type parameters to useState(null) calls where the setter later receives string, boolean, number, or known string-union values. TypeScript infers the state type as null, causing TS2345/TS2322 errors when passing non-null values to the setter.

What changed

Each useState(null) was changed to useState<Type | null>(null) where Type matches the actual values passed to the setter:

File State variable Type parameter
commands/btw/btw.tsx response, error string | null
commands/mcp/MCPReconnect.tsx error string | null
commands/rate-limit-options/rate-limit-options.tsx subCommandJSX React.ReactNode | null
commands/tag/tag.tsx sessionId string | null
commands/thinkback/thinkback.tsx installError, skillDir, hasGenerated string | null, string | null, boolean | null
components/AutoUpdaterWrapper.tsx useNativeInstaller, isPackageManager boolean | null
components/DesktopHandoff.tsx error string | null
components/PromptInput/PromptInputFooterLeftSide.tsx remainingSeconds number | null
components/TeleportError.tsx currentError TeleportLocalErrorType | null
components/TeleportRepoMismatchDialog.tsx errorMessage string | null
components/ThinkingToggle.tsx confirmationPending boolean | null

Why

useState(null) infers the state type as null, making setX(someString) a type error. Adding the explicit type parameter is the canonical React fix. It does not change runtime behavior — the state still initializes as null.

Complex object types (GroveConfig | null, EnvironmentResource | null, LogTreeNode | null, etc.) and deeply multi-state components (LogSelector.tsx, PluginSettings.tsx, Doctor.tsx) are deferred to follow-up PRs to keep this review manageable.

Validation

  • git diff --check — passed
  • bun run typecheck — zero SetStateAction<null> errors in modified files (was ~22)
  • All type parameters verified against actual setter usage in each file
  • React already imported in rate-limit-options.tsx (no new imports needed)
  • TeleportLocalErrorType already defined and exported in TeleportError.tsx

Summary by CodeRabbit

  • Refactor
    • Enhanced TypeScript type annotations across the application to improve code stability, maintainability, and long-term reliability. No user-facing changes or behavioral modifications.

When useState(null) is used for state that later accepts string,
boolean, or number values, TypeScript infers the state type as
null, making the setter reject non-null values (TS2345, TS2322).

This adds explicit type parameters to 11 files in the simplest
cases: string, boolean, number, and known string unions.

  components/mcp/MCPReconnect.tsx       string | null
  commands/btw/btw.tsx                  string | null  (error + response)
  commands/tag/tag.tsx                   string | null  (sessionId)
  commands/rate-limit-options/           ReactNode | null
  commands/thinkback/thinkback.tsx       string | null, boolean | null
  components/TeleportError.tsx            TeleportLocalErrorType | null
  components/TeleportRepoMismatchDialog  string | null
  components/DesktopHandoff.tsx          string | null
  components/ThinkingToggle.tsx          boolean | null
  components/AutoUpdaterWrapper.tsx      boolean | null (2 states)
  components/PromptInputFooterLeftSide   number | null

Complex object types (GroveConfig, EnvironmentResource, etc.) and
deeply multi-state components (LogSelector, PluginSettings, Doctor)
are deferred to follow-up PRs.

Refs: Gitlawb#1486
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f3585ef1-e794-478a-a1e5-2d0310bafa2d

📥 Commits

Reviewing files that changed from the base of the PR and between 343cd1a and aefe9ed.

📒 Files selected for processing (11)
  • src/commands/btw/btw.tsx
  • src/commands/rate-limit-options/rate-limit-options.tsx
  • src/commands/tag/tag.tsx
  • src/commands/thinkback/thinkback.tsx
  • src/components/AutoUpdaterWrapper.tsx
  • src/components/DesktopHandoff.tsx
  • src/components/PromptInput/PromptInputFooterLeftSide.tsx
  • src/components/TeleportError.tsx
  • src/components/TeleportRepoMismatchDialog.tsx
  • src/components/ThinkingToggle.tsx
  • src/components/mcp/MCPReconnect.tsx
📜 Recent review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: smoke-and-tests
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/components/TeleportRepoMismatchDialog.tsx
  • src/components/PromptInput/PromptInputFooterLeftSide.tsx
  • src/components/mcp/MCPReconnect.tsx
  • src/commands/tag/tag.tsx
  • src/components/ThinkingToggle.tsx
  • src/commands/btw/btw.tsx
  • src/components/TeleportError.tsx
  • src/commands/rate-limit-options/rate-limit-options.tsx
  • src/components/DesktopHandoff.tsx
  • src/commands/thinkback/thinkback.tsx
  • src/components/AutoUpdaterWrapper.tsx
🔇 Additional comments (11)
src/commands/btw/btw.tsx (1)

43-44: LGTM!

src/commands/rate-limit-options/rate-limit-options.tsx (1)

30-30: LGTM!

src/commands/tag/tag.tsx (1)

79-79: LGTM!

src/commands/thinkback/thinkback.tsx (1)

393-395: LGTM!

src/components/ThinkingToggle.tsx (1)

28-28: LGTM!

src/components/mcp/MCPReconnect.tsx (1)

25-25: LGTM!

src/components/AutoUpdaterWrapper.tsx (1)

29-30: LGTM!

src/components/DesktopHandoff.tsx (1)

33-33: LGTM!

src/components/PromptInput/PromptInputFooterLeftSide.tsx (1)

77-77: LGTM!

src/components/TeleportError.tsx (1)

28-28: LGTM!

src/components/TeleportRepoMismatchDialog.tsx (1)

24-24: LGTM!


📝 Walkthrough

Walkthrough

TypeScript type annotations are added to React state declarations across 11 component files. Each useState hook receives an explicit generic type parameter (string | null, boolean | null, React.ReactNode | null, or TeleportLocalErrorType | null) instead of inferring types from null initialization. No runtime behavior is modified.

Changes

useState Type Annotations

Layer / File(s) Summary
useState generic type parameters
src/commands/btw/btw.tsx, src/commands/rate-limit-options/rate-limit-options.tsx, src/commands/tag/tag.tsx, src/commands/thinkback/thinkback.tsx, src/components/AutoUpdaterWrapper.tsx, src/components/DesktopHandoff.tsx, src/components/PromptInput/PromptInputFooterLeftSide.tsx, src/components/TeleportError.tsx, src/components/TeleportRepoMismatchDialog.tsx, src/components/ThinkingToggle.tsx, src/components/mcp/MCPReconnect.tsx
React state hooks are updated with explicit TypeScript generic type parameters: response and error in BtwSideQuestion use string | null; subCommandJSX in RateLimitOptionsMenu uses React.ReactNode | null; sessionId in ToggleTagAndClose uses string | null; installError, skillDir, and hasGenerated in ThinkbackFlow use string | null and boolean | null; useNativeInstaller and isPackageManager in AutoUpdaterWrapper use boolean | null; error in DesktopHandoff uses string | null; remainingSeconds in ProactiveCountdown uses number | null; currentError in TeleportError uses TeleportLocalErrorType | null; errorMessage in TeleportRepoMismatchDialog uses string | null; confirmationPending in ThinkingToggle uses boolean | null; error in MCPReconnect uses string | null.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Suggested reviewers

  • jatmn
  • kevincodex1
🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately and concisely describes the main change: adding explicit type parameters to useState(null) hooks to fix TypeScript type inference errors.
Description check ✅ Passed Description is comprehensive and well-structured, covering summary, what changed with a detailed table, why the change was needed, validation steps, and scope boundaries.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Risk Surface Disclosed ✅ Passed PR touches MCP/plugins, startup, and auth areas but makes only TypeScript type annotations to useState hooks with zero runtime logic or behavioral changes, introducing no risk.
No Hidden Policy Change ✅ Passed PR contains only TypeScript type annotations for useState in React components with zero behavioral changes or hidden policy/routing/telemetry/permission modifications in runtime code.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the contribution. I do not see any actionable issues from my review.

@kevincodex1

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@kevincodex1 kevincodex1 merged commit 0e30ee8 into Gitlawb:main Jun 9, 2026
3 checks passed
@chioarub chioarub deleted the pr-usestate-null branch June 9, 2026 05:52
deagwon97 pushed a commit to deagwon97/openclaude that referenced this pull request Jun 11, 2026
…itlawb#1513)

When useState(null) is used for state that later accepts string,
boolean, or number values, TypeScript infers the state type as
null, making the setter reject non-null values (TS2345, TS2322).

This adds explicit type parameters to 11 files in the simplest
cases: string, boolean, number, and known string unions.

  components/mcp/MCPReconnect.tsx       string | null
  commands/btw/btw.tsx                  string | null  (error + response)
  commands/tag/tag.tsx                   string | null  (sessionId)
  commands/rate-limit-options/           ReactNode | null
  commands/thinkback/thinkback.tsx       string | null, boolean | null
  components/TeleportError.tsx            TeleportLocalErrorType | null
  components/TeleportRepoMismatchDialog  string | null
  components/DesktopHandoff.tsx          string | null
  components/ThinkingToggle.tsx          boolean | null
  components/AutoUpdaterWrapper.tsx      boolean | null (2 states)
  components/PromptInputFooterLeftSide   number | null

Complex object types (GroveConfig, EnvironmentResource, etc.) and
deeply multi-state components (LogSelector, PluginSettings, Doctor)
are deferred to follow-up PRs.

Refs: Gitlawb#1486
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