Skip to content

chore(ts): migrate all components/ to TypeScript#52

Merged
oxyc merged 9 commits into
mainfrom
chore/ts-components
May 30, 2026
Merged

chore(ts): migrate all components/ to TypeScript#52
oxyc merged 9 commits into
mainfrom
chore/ts-components

Conversation

@oxyc

@oxyc oxyc commented May 30, 2026

Copy link
Copy Markdown
Member

Follow-up to #41: migrate every remaining components/*.jsx + the two .js helpers to TypeScript. No behaviour change — pure type addition over the existing logic.

Files

15 components total. All previously .jsx/.js; now .tsx/.ts. The UndoContext smoke migration from PR #47 was already TS — this PR finishes the rest.

File LOC Notes
panel-geometry.ts 124 Typed PanelSize / PanelPosition exports
skills-cache.ts 90 Skill interface, narrowed REST row mapping
ReadAloudController.tsx 159 Typed ProgressState map
memory-dataview.tsx 161 Field<MemoryRecord>[], View, Operator from @wordpress/dataviews
conversations-dataview.tsx 296 Same dataviews pattern; typed ConversationRow shape
Composer.tsx 405 Typed sub-components (SlashAutocomplete, SelectionChip, ComposerAttachment)
ToolCallFallback.tsx 356 Typed ToolDiff, DiffViewerProps, exported ToolCallFallbackProps
Messages.tsx 426 Typed AnyMessagePart, BlockChipProps, narrowed wp.data block-editor access
MicButton.tsx 391 Typed VoiceLang, narrowed useTtsEnabled/useVoiceMode JS-hook tuples
assistant-modal.tsx ~340 Exports PendingApproval (reused by Thread)
skills-dataview.tsx ~430 Dataviews + typed schedule literal union
Thread.tsx ~480 Imports PendingApproval from assistant-modal
SidePanels.tsx ~500 Local ModelsConfig / ModelProvider / ModelOption for window.gdsAssistant.models
mcp-servers-dataview.tsx ~620 AuthType literal union, narrowed Modal/Notice prop boundaries
types/globals.d.ts NEW Shared GdsAssistantGlobal interface — was previously redeclared piecemeal in use-runtime-adapter.ts; extracted so every module sees the same merged shape

Type-shape decisions

  • window.gdsAssistant extracted to types/globals.d.ts so skills-cache, dataviews, and use-runtime-adapter don't race to redeclare the same global with incompatible shapes (the original conflict surfaced an unknown intersection that broke X-WP-Nonce headers).
  • PendingApproval defined once in assistant-modal.tsx with the trustableHost field used by the approval bar — Thread.tsx imports it rather than redeclaring.
  • apiFetch calls returning Response (when parse: false) cast at the call site ((await apiFetch({...})) as Response) since apiFetch returns Promise<unknown> by default.
  • Library boundaries cast rather than restated:
    • Fallback slot in Messages.tsx casts to unknown as never (the library prop type carries internal runtime bookkeeping — status, addResult, resume — we don't read).
    • assistant-ui's readonly s.content tuple union cast to readonly AnyMessagePart[] inside selectors.
    • useTtsEnabled / useVoiceMode tuples narrowed at destructure until use-tts.js itself migrates.
  • No GDS components' prop interfaces were widened to weaken behaviour; where the library type was actually narrower than what we use, the cast carries a one-line comment explaining why.

What stayed .js

The 3 hooks in resources/scripts/hooks/ (use-tts.js, use-voice-input.js, use-editor-selection.js) — out of scope here. Each can migrate independently in a follow-up; the components that consume them already narrow the tuple shape locally.

Verification

Commits

9 commits, individually reviewable:

  1. ead80cd — panel-geometry, skills-cache, ReadAloudController, memory-dataview, conversations-dataview, Composer + globals.d.ts
  2. c5d81c4 — ToolCallFallback, Messages
  3. 8163ae5 — MicButton
  4. 56b4e59 — assistant-modal
  5. ce8a400 — skills-dataview
  6. 8f7ec78 — Thread
  7. b3a6203 — SidePanels
  8. abfd99c — mcp-servers-dataview
  9. 484f5e8lint:fix:js autofix sweep across the freshly-migrated files

🤖 Generated with Claude Code

oxyc and others added 9 commits May 29, 2026 20:21
…y, skills-cache, ReadAloudController, memory-dataview, conversations-dataview, Composer)

Checkpoint within the components/ migration. Adds:

- types/globals.d.ts — shared GdsAssistantGlobal interface (extracted from
  use-runtime-adapter.ts so every module sees the same merged shape and
  skills-cache + dataviews don't race to redeclare `window.gdsAssistant`)
- panel-geometry.ts — pure utilities, typed PanelSize / PanelPosition
- skills-cache.ts — typed Skill interface + REST row narrowing
- ReadAloudController.tsx — typed ProgressState map
- memory-dataview.tsx — wired through Field<MemoryRecord> + View + Operator from @wordpress/dataviews
- conversations-dataview.tsx — same dataviews pattern with ConversationRow
- Composer.tsx — typed sub-components (SlashAutocomplete, SelectionChip, ComposerAttachment) + handlers

`npm run typecheck` clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Continues the components/ pass. Both files use typed local interfaces for
the message-part shapes assistant-ui passes through (AnyMessagePart,
ToolDiff, BlockChipProps etc.) and cast at the library boundary where
the library's type carries internal bookkeeping (status, addResult,
resume on the Fallback prop; readonly tuple union on s.content).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Voice dictation + voice-mode (auto-send) component. Adds local VoiceLang
shape, narrows the useTtsEnabled / useVoiceMode tuples from the JS hook
modules until those migrate too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add typed AssistantModalProps and PendingApproval interfaces. Type all
useState/useRef/useCallback hooks and DOM event handlers. Pure type
addition — no behaviour changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Typed FIELDS as Field<SkillRow>[] and DEFAULT_VIEW as View. Introduced
SkillRow / ExportedSkill / EditingSkill interfaces and typed the modal
sub-component. Cast schedule value at SelectControl since its literal
union doesn't match our string-typed state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Added ThreadProps interface and TranscriptMessage/Part shapes for the
Markdown serializer. Imports PendingApproval from assistant-modal and
ConversationSummary from the runtime adapter. Runtime messages narrowed
via unknown cast since the thread runtime types its messages as a
readonly internal union.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Export typed props for every panel (PanelHeader, SystemContextInput,
SkillsList, ConversationList). Type useState/useCallback handlers and
the SessionUsageSnapshot subscription. Window globals (models config,
defaultMaxTokens) read via local cast rather than augmenting the global
type — they're consumed in only two spots.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Added ServerRow / AuthDetail / NoticeState / AuthPayload interfaces and
typed both the list view and the add/edit modal. AuthType narrowed to a
union; SelectControl onChange casts back to the union since the library
types its callback as a generic string. Notice style prop is spread via
a cast because @types/wordpress__components omits it (the runtime
forwards it to the wrapper div).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prettier reformatting (import collapsing, paren wrapping) plus
jsdoc/require-param additions across the just-migrated .tsx files and a
handful of previously-migrated files that share the components folder.
Manually stripped the noisy `@param root0.X` blocks the autofix
inserted on assistant-modal and SidePanels — the destructured props are
already documented through the typed interface.

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