TypeScript error: stopPropagation does not exist on KeyEvent type (#7443) #4493

Closed
opened 2026-02-16 17:44:21 -05:00 by yindo · 2 comments
Owner

Originally created by @CasualDeveloper on GitHub (Jan 9, 2026).

Originally assigned to: @rekram1-node on GitHub.

Bug Description

The useKeyboard callback in dialog.tsx uses evt.stopPropagation(), but TypeScript reports:

TS2339: Property 'stopPropagation' does not exist on type 'KeyEvent'

Root Cause Analysis

The KeyEvent class in @opentui/core does have stopPropagation() properly typed:

// node_modules/@opentui/core/lib/KeyHandler.d.ts
export declare class KeyEvent implements ParsedKey {
  // ...
  preventDefault(): void;
  stopPropagation(): void;  // ✓ Exists
}

And @opentui/solid has properly typed exports in src/elements/hooks.d.ts:

export declare const useKeyboard: (callback: (key: KeyEvent) => void, options?: UseKeyboardOptions) => void;

However, the jsx-runtime.d.ts contains:

import type { DomNode } from "./dist"  // ← This pulls in dist/index.d.ts

And dist/index.d.ts has auto-generated loose types:

export function useKeyboard(callback: any, options: any): void;  // ← Types lost

When TypeScript resolves imports via the jsx-runtime (required for JSX components), it also loads dist/index.d.ts, which shadows the properly-typed exports with any types. But when using noImplicitAny or when the any type flows through, TypeScript can't infer that evt.stopPropagation() exists.

Impact

  • bun turbo typecheck fails
  • Pre-push hooks fail (blocking pushes without --no-verify)
  • Build still succeeds (Bun bundler doesn't type-check)

Reproduction

cd packages/opencode
bunx tsc --noEmit src/cli/cmd/tui/ui/dialog.tsx

Introduced In

Commit 1f9e195cd8ce6d9dcca4c966a7c9ba2f6222f29d ("stop esc propagation from dialogs")

Affected Code

// packages/opencode/src/cli/cmd/tui/ui/dialog.tsx:59-67
useKeyboard((evt) => {
  if (evt.name === "escape" && store.stack.length > 0) {
    const current = store.stack.at(-1)!
    current.onClose?.()
    setStore("stack", store.stack.slice(0, -1))
    evt.preventDefault()
    evt.stopPropagation()  // ← Error here
    refocus()
  }
})

Fix: Import KeyEvent type explicitly (#7443)

import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid"
import type { KeyEvent } from "@opentui/core"  // Add explicit import

// Then either annotate the callback:
useKeyboard((evt: KeyEvent) => {
  // ...
})

Environment

  • opencode version: v1.1.8+
  • @opentui/solid version: 0.1.70
  • @opentui/core version: 0.1.70
Originally created by @CasualDeveloper on GitHub (Jan 9, 2026). Originally assigned to: @rekram1-node on GitHub. ## Bug Description The `useKeyboard` callback in `dialog.tsx` uses `evt.stopPropagation()`, but TypeScript reports: ``` TS2339: Property 'stopPropagation' does not exist on type 'KeyEvent' ``` ## Root Cause Analysis The `KeyEvent` class in `@opentui/core` **does** have `stopPropagation()` properly typed: ```typescript // node_modules/@opentui/core/lib/KeyHandler.d.ts export declare class KeyEvent implements ParsedKey { // ... preventDefault(): void; stopPropagation(): void; // ✓ Exists } ``` And `@opentui/solid` has properly typed exports in `src/elements/hooks.d.ts`: ```typescript export declare const useKeyboard: (callback: (key: KeyEvent) => void, options?: UseKeyboardOptions) => void; ``` **However**, the `jsx-runtime.d.ts` contains: ```typescript import type { DomNode } from "./dist" // ← This pulls in dist/index.d.ts ``` And `dist/index.d.ts` has auto-generated loose types: ```typescript export function useKeyboard(callback: any, options: any): void; // ← Types lost ``` When TypeScript resolves imports via the jsx-runtime (required for JSX components), it also loads `dist/index.d.ts`, which shadows the properly-typed exports with `any` types. But when using `noImplicitAny` or when the `any` type flows through, TypeScript can't infer that `evt.stopPropagation()` exists. ## Impact - `bun turbo typecheck` fails - Pre-push hooks fail (blocking pushes without `--no-verify`) - Build still succeeds (Bun bundler doesn't type-check) ## Reproduction ```bash cd packages/opencode bunx tsc --noEmit src/cli/cmd/tui/ui/dialog.tsx ``` ## Introduced In Commit `1f9e195cd8ce6d9dcca4c966a7c9ba2f6222f29d` ("stop esc propagation from dialogs") ## Affected Code ```typescript // packages/opencode/src/cli/cmd/tui/ui/dialog.tsx:59-67 useKeyboard((evt) => { if (evt.name === "escape" && store.stack.length > 0) { const current = store.stack.at(-1)! current.onClose?.() setStore("stack", store.stack.slice(0, -1)) evt.preventDefault() evt.stopPropagation() // ← Error here refocus() } }) ``` ## Fix: Import KeyEvent type explicitly (#7443) ```typescript import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid" import type { KeyEvent } from "@opentui/core" // Add explicit import // Then either annotate the callback: useKeyboard((evt: KeyEvent) => { // ... }) ``` ## Environment - opencode version: v1.1.8+ - @opentui/solid version: 0.1.70 - @opentui/core version: 0.1.70
yindo added the opentui label 2026-02-16 17:44:21 -05:00
yindo closed this issue 2026-02-16 17:44:21 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 9, 2026):

This issue might be a duplicate or closely related to existing keyboard event handling issues in dialogs. Please check:

  • #7384: TUI: Commands modal passes Esc key 'through to the model - related to keyboard event propagation in dialog components
  • #7398: Text editing shortcuts don't work in search dialogs - related to keyboard event handling in the useKeyboard hook from @opentui/solid

The root cause in these issues also involves keyboard event handling in dialog components using the same useKeyboard callback pattern.

@github-actions[bot] commented on GitHub (Jan 9, 2026): This issue might be a duplicate or closely related to existing keyboard event handling issues in dialogs. Please check: - #7384: TUI: Commands modal passes `Esc` key 'through to the model - related to keyboard event propagation in dialog components - #7398: Text editing shortcuts don't work in search dialogs - related to keyboard event handling in the useKeyboard hook from @opentui/solid The root cause in these issues also involves keyboard event handling in dialog components using the same `useKeyboard` callback pattern.
Author
Owner

@CasualDeveloper commented on GitHub (Jan 18, 2026):

Closing as obsolete: can’t reproduce on origin/dev anymore; bun turbo typecheck is clean; no action needed.

@CasualDeveloper commented on GitHub (Jan 18, 2026): Closing as obsolete: can’t reproduce on origin/dev anymore; bun turbo typecheck is clean; no action needed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#4493