Skip to content

types: improve type safety in web demo cast fixtures - #4626

Merged
georgi merged 1 commit into
mainfrom
types/demo-cast-workflow-shapes
Aug 1, 2026
Merged

types: improve type safety in web demo cast fixtures#4626
georgi merged 1 commit into
mainfrom
types/demo-cast-workflow-shapes

Conversation

@claude

@claude claude Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

What I looked for

web/src/, electron/src/, and mobile/src/ are already free of any in non-test source — every hit for : any, as any, any[], Record<string, any>, Promise<any> outside tests turned out to be the English word "any" inside a comment. The real weak spot is as unknown as, which silences the compiler completely. This PR fixes the largest cluster of those that has a single fixable root cause.

The bug in the types

Ten synthetic demo casts each ended their workflow literal with as unknown as Workflow. That double cast meant nothing checked the fixtures against the transport shape — a cast could drift into an unplayable graph and still compile.

The root cause was one line. castHelpers.GraphNode declared:

dynamic_outputs: Record<string, unknown>;

which is not assignable to the protocol Node's Record<string, PropertyTypeMetadata>. Everything else in those literals already conformed — verified by annotating a probe and reading the single resulting error.

Changes

File What improved
web/src/demo/castHelpers.ts GraphNode now extends Node (the transport type) so it can't drift again; dynamic_outputs typed Record<string, PropertyTypeMetadata>; edge() given an explicit Edge return type
web/src/demo/cookbook/builders.ts cookbookWorkflow returns a checked Workflow; edges param typed Edge[] instead of ReturnType<typeof edge>[]
chatQaCast.ts, connectRunCast.ts, describeImageCast.ts, listGeneratorCast.ts, sampleCast.ts, summarizeCast.ts, templateMergeCast.ts, tutorialCast.ts as unknown as Workflowconst workflow: Workflow, so each fixture is now checked against the real API shape

Compile-time only — no runtime behavior changed.

Verifying the annotations aren't vacuous

Node has an index signature, so an annotation could in principle check nothing. Confirmed it does check: temporarily setting name: 123 in connectRunCast.ts produces

src/demo/connectRunCast.ts(28,3): error TS2322: Type 'number' is not assignable to type 'string'.

Reverted after the check.

Checks

npm run typecheck ✅ · npm run lint ✅ · npm run test ✅ (1063 + 63 + 73 suites, 14132 tests)

Deliberately left out

  • web/src/e2e_runner/graphRender.ts:129 has the same as unknown as Workflow and the same root cause, so it's a one-line follow-up. Left out only to stay within the 10-file cap.
  • The tRPC → ApiTypes casts (WorkflowManagerStore, useWorkflowVersions, AssetStore, GlobalChatStore, electron/src/api.ts, mobile/src/hooks/useApplications.ts) are the higher-stakes cluster, and I did not paper over them. They hide a genuine nullability mismatch: the router infers description: string | null | undefined while the protocol Workflow declares description: string, and workflows.examples returns workflows: unknown[]. Fixing it properly means changing packages/protocol (outside this task's scope) or adding ?? "" normalizers at the boundary (a runtime change this task forbids). Worth its own PR — it's a real defect, not a typing nit.

🤖 Generated with Claude Code

Ten synthetic demo casts built their workflow with `as unknown as Workflow`,
so nothing checked them against the transport shape — a cast could drift into
an unplayable graph and still compile.

One root cause: `castHelpers.GraphNode` declared `dynamic_outputs` as
`Record<string, unknown>`, which is not assignable to the protocol `Node`'s
`Record<string, PropertyTypeMetadata>`. Everything else already conformed.

GraphNode now extends the transport `Node` (so it can't drift again), `edge()`
returns `Edge`, and the ten double casts are gone in favor of plain
annotations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@georgi
georgi merged commit 876d5f6 into main Aug 1, 2026
23 checks passed
@georgi
georgi deleted the types/demo-cast-workflow-shapes branch August 1, 2026 09:17
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