Skip to content

chore(ts): migrate remaining hooks + editor/selection to TypeScript#53

Merged
oxyc merged 1 commit into
mainfrom
chore/ts-hooks
May 30, 2026
Merged

chore(ts): migrate remaining hooks + editor/selection to TypeScript#53
oxyc merged 1 commit into
mainfrom
chore/ts-hooks

Conversation

@oxyc

@oxyc oxyc commented May 30, 2026

Copy link
Copy Markdown
Member

Last batch of the TS migration (#41 follow-up). Closes out the JS-side of resources/scripts/: the only .js files left are CI/test configs.

Files

File LOC Notes
editor/selection.ts (from .js) 274 Exports discriminated SelectionContext union (TextRangeSelection / WholeBlockSelection / MultiBlockSelection) consumers can switch on mode. Local WpSurface narrow shape for wp.data/wp.richText read via a one-call wp() helper.
hooks/use-editor-selection.ts (from .js) 84 Returns SelectionContext | null; discriminated narrowing in sameSelection.
hooks/use-voice-input.ts (from .js) 130 Local SpeechRecognitionInstance / SpeechRecognitionEvent / SpeechRecognitionConstructor for the Web Speech API surface. Reads the globals via getSpeechRecognition() to dodge lib.dom.d.ts conflicts around the vendor-prefixed names. Exports UseVoiceInputOptions + UseVoiceInput interfaces.
hooks/use-tts.ts (from .js) 378 useTtsEnabled / useVoiceMode now return real [boolean, (value: boolean) => void] tuples — MicButton.tsx can drop its manual narrowing cast in a follow-up. Local ReadableMessage shape for extractAssistantText.

Design notes

  • Window.wp is intentionally NOT declared globally here. editor-bridge.ts already declares the much wider wp.data overload set (dispatch + select for multiple stores); selection.ts needs a strictly narrower surface. Each module reads via a local cast ((window as { wp?: ... }).wp) so the two shapes don't have to merge.
  • SpeechRecognition likewise — lib.dom.d.ts ships it but typings vary across TS releases. Reading via a local cast keeps the hook compiling cleanly on every release.
  • useTtsEnabled / useVoiceMode return signatures now bind statically — MicButton.tsx's as [boolean, (v: boolean) => void] cast at the destructure becomes redundant. Left for a follow-up to keep this PR pure-migration.

Verification

  • npm run typecheck — clean
  • npm run lint:js0 warnings, 0 errors
  • npm run build — succeeds
  • npm run test:unit — 17/17 pass

Wraps up #41

After this lands, every .js/.jsx file in resources/scripts/ (except CI/test configs) is TypeScript. The full migration arc:

PR Files
#47 Toolchain + UndoContext smoke
#48 editor-bridge.ts
#49 types/runtime.ts shared module
#50 use-runtime-adapter.ts
#52 All components/*.jsx
this editor/selection.ts, use-editor-selection.ts, use-voice-input.ts, use-tts.ts

🤖 Generated with Claude Code

Last batch of the TS migration (#41 follow-up). Closes out the JS-side of
`resources/scripts/`: the only `.js` files left are CI/test configs.

## Files

- `editor/selection.ts` (from `.js`, 274 LOC)
  - Exports a discriminated `SelectionContext` union — `TextRangeSelection`,
    `WholeBlockSelection`, `MultiBlockSelection` — that consumers can `switch`
    on `mode`. `useEditorSelection` and `Composer.tsx`'s `SelectionChip` both
    pick this up automatically.
  - Local `WpSurface` narrow shape for the `wp.data` / `wp.richText` bits
    it touches, read via a one-call `wp()` helper to avoid colliding with
    `editor-bridge.ts`'s different `wp.data` overloads.
- `hooks/use-editor-selection.ts` (from `.js`)
  - Returns `SelectionContext | null` from the shared selection module;
    discriminated narrowing in `sameSelection`.
- `hooks/use-voice-input.ts` (from `.js`)
  - Local `SpeechRecognitionInstance` / `SpeechRecognitionEvent` /
    `SpeechRecognitionConstructor` for the Web Speech API surface we use,
    fetched via `getSpeechRecognition()` to dodge lib.dom.d.ts conflicts
    around the vendor-prefixed globals.
  - Exports `UseVoiceInputOptions` + `UseVoiceInput` interfaces.
- `hooks/use-tts.ts` (from `.js`, 378 LOC)
  - Typed `useTtsEnabled` / `useVoiceMode` to return real
    `[boolean, (value: boolean) => void]` tuples — `MicButton.tsx` can now
    drop its manual narrowing cast (will follow up).
  - Local `ReadableMessage` shape for what `extractAssistantText` reads
    (string content OR a readonly array of `{type, text}` parts).

## Verification

- `npm run typecheck` — clean
- `npm run lint:js` — 0 warnings, 0 errors
- `npm run build` — succeeds
- `npm run test:unit` — 17/17 pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@oxyc oxyc merged commit 982ac13 into main May 30, 2026
3 checks passed
@oxyc oxyc deleted the chore/ts-hooks branch May 30, 2026 00: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.

1 participant