Skip to content

fix(website): stop reading union-only fields off heterogeneous data - #15282

Merged
christian-byrne merged 1 commit into
mainfrom
glary/website-fix-union-type-errors
Aug 15, 2026
Merged

fix(website): stop reading union-only fields off heterogeneous data#15282
christian-byrne merged 1 commit into
mainfrom
glary/website-fix-union-type-errors

Conversation

@christian-byrne

Copy link
Copy Markdown
Contributor

PR Created by the Glary-Bot Agent


Summary

Fixes 6 of the 9 pre-existing vue-tsc errors in apps/website, both caused by reading a field that does not exist on every member of a union. First of three stacked PRs that end with vue-tsc running in CI.

Changes

  • What:
    • templates/mcp/mcpDemoPrompts.ts — the array was declared as const satisfies readonly McpDemoPrompt[]. satisfies checks assignability but preserves the as const type, so the array became a union of nine distinct literal shapes rather than McpDemoPrompt[]. Since no single member declares all of via / variants / stacked, every read of those optional fields failed (5 errors in ComfyMcpDemo.vue). Annotating as readonly McpDemoPrompt[] restores the intended optional fields and matches how data/drops.ts declares its data. No consumer depended on the literal types.
    • templates/drops/DropsSection.vuedrop.media.poster was read without narrowing DropMedia on its type discriminant; poster only exists on the video member. Now narrowed with drop.media.type === 'video' ? drop.media.poster : undefined.
  • Breaking: none. Both changes are type-level only — see Review Focus.

Review Focus

Neither change alters runtime behaviour:

  • DropsSection: for type: 'video' the value still comes from drop.media.poster; for images the property access already evaluated to undefined at runtime, which is exactly what the ternary now yields. Confirmed no drop in data/drops.ts passes a poster — all three videoFor(...) calls take only (fileName, alt) — so the rendered output is byte-identical.
  • mcpDemoPrompts: dropping as const only widens literal types to their declared ones. The values are unchanged.

These were invisible until now because .vue files are type-checked by nothing in this repo — that gap is fixed in the third PR of this stack.

Verification

astro check 0 errors · vue-tsc drops from 9 errors to 3 (the remaining 3 are fixed in the next PR) · 422 unit tests passing (1 pre-existing minimaxMusic3 .jpeg failure, also fails on main) · lint/format/knip clean · production build 595 pages.

Manually verified the MCP hero demo in a production build (screenshot below) — all three optional fields still render exactly as before:

  • variants: 4 → Character Concepts shows 4 separate thumbnails
  • stacked: true → Keyframe Board shows the offset layers behind the thumbnail
  • via → NOTION / FIGMA / BLENDER badges render, and cards without via (Set Extension) correctly show none

Also loaded /launches (DropsSection): 3 videos, 0 with a poster attribute (matching the data), 31 images, none with a broken src, and no page errors.

Screenshots

MCP hero demo after the change: variants render 4 thumbnails, stacked renders offset layers, via badges render

mcpDemoPrompts was declared `as const satisfies readonly McpDemoPrompt[]`,
so each element kept its exact literal type and the array became a union
of nine shapes. Reading the optional via/variants/stacked off that union
fails because no single member declares all three. Annotating the array
as readonly McpDemoPrompt[] restores the intended optional fields, and
matches how drops.ts declares its data.

DropsSection read media.poster without narrowing DropMedia on its type
discriminant, and poster only exists on the video member.

Both were invisible because .vue files are not type-checked today.
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown

🌐 Website E2E

Tip

All tests passed.

Status ✅ Passed
Report View Report

🔗 Website Preview

Website Preview: https://comfy-website-preview-pr-15282.vercel.app

This commit: https://website-frontend-f97tl2fnu-comfyui.vercel.app

Last updated: 2026-08-14T22:23:34Z for c02bdc7

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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: 7bf28405-40c5-46a2-9d22-c76e247463d6

📥 Commits

Reviewing files that changed from the base of the PR and between 4c5afc8 and c02bdc7.

📒 Files selected for processing (2)
  • apps/website/src/templates/drops/DropsSection.vue
  • apps/website/src/templates/mcp/mcpDemoPrompts.ts

📝 Walkthrough

Walkthrough

The drops template now passes poster data only for video media. The MCP demo prompt list now uses an explicit readonly McpDemoPrompt[] type.

Changes

Drops media handling

Layer / File(s) Summary
Conditional video poster
apps/website/src/templates/drops/DropsSection.vue
The poster value is provided only for video media. Non-video media receives undefined.

MCP prompt typing

Layer / File(s) Summary
Explicit prompt array type
apps/website/src/templates/mcp/mcpDemoPrompts.ts
mcpDemoPrompts is explicitly typed as readonly McpDemoPrompt[], replacing the previous as const satisfies assertion.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to c02bd

This PR makes localized type-safety fixes without changing intended runtime behavior, so no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers: imick-io

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
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.
End-To-End Regression Coverage For Fixes ✅ Passed PASS: The changed files are exclusively under apps/website, and the check explicitly excludes such changes from failure.
Adr Compliance For Entity/Litegraph Changes ✅ Passed The changed files are outside src/lib/litegraph/, src/ecs/, and graph-entity files, so this ADR check does not apply.
Title check ✅ Passed The title clearly identifies the main fix: preventing reads of fields that exist only on some union members.
Description check ✅ Passed The description includes the required summary, changes, breaking status, review focus, verification details, and applicable screenshot.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch glary/website-fix-union-type-errors

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

@github-actions github-actions Bot added the risk:R1 PR risk grade (advisory shadow check; grader-owned) label Aug 14, 2026
@christian-byrne
christian-byrne marked this pull request as ready for review August 15, 2026 01:17
@christian-byrne
christian-byrne requested a review from a team August 15, 2026 01:17
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Aug 15, 2026
toolKey: 'mcp.hero.demoToolSetExtension',
result: 'set_extension.png'
}
] as const satisfies readonly McpDemoPrompt[]

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.

The inference here is slightly different.

@DrJKL DrJKL assigned christian-byrne and unassigned DrJKL Aug 15, 2026
@christian-byrne
christian-byrne added this pull request to the merge queue Aug 15, 2026
Merged via the queue into main with commit 19452ac Aug 15, 2026
64 checks passed
@christian-byrne
christian-byrne deleted the glary/website-fix-union-type-errors branch August 15, 2026 01:41
christian-byrne added a commit that referenced this pull request Aug 16, 2026
…#15300)

*PR Created by the Glary-Bot Agent*

---

## Summary

`astro/tsconfigs/strictest` layers nine options on top of the `strict`
preset the app already uses. Measured each against `apps/website`: seven
report zero errors once six dead declarations are removed. This turns
those seven on.

## Changes

- **What**: enables `noUnusedLocals`, `noUnusedParameters`,
`noImplicitReturns`, `noFallthroughCasesInSwitch`, `noImplicitOverride`,
`allowUnreachableCode: false`, `allowUnusedLabels: false`, and deletes
the six declarations that blocked them:
  - `data/drops.ts` — `FEATURED_BADGE` (unused `LocalizedText`)
  - `layouts/BaseLayout.astro` — unused `Locale` type import
- `pages/careers.astro` + `pages/zh-CN/careers.astro` — `siteUrl`
destructured but never read
  - `scripts/generate-models.ts` — unused `RawModel` interface
- `components/product/enterprise/TeamSection.vue` — `routes` computed
and its `getRoutes` import
- **Breaking**: none. Every deletion is a declaration with no reader.

## Review Focus

**Measured, not guessed.** Error counts per flag against this app:

| flag | errors | enabled here |
|---|---:|:---:|
| `noUnusedParameters` | 0 | yes |
| `noImplicitReturns` | 0 | yes |
| `noFallthroughCasesInSwitch` | 0 | yes |
| `noImplicitOverride` | 0 | yes |
| `allowUnreachableCode: false` | 0 | yes |
| `allowUnusedLabels: false` | 0 | yes |
| `noUnusedLocals` | 6 | yes (fixed here) |
| `exactOptionalPropertyTypes` | **75** | no |
| `noUncheckedIndexedAccess` | **202** | no |

The last two are left off deliberately — each needs its own remediation
pass, not a flag flip. `noUncheckedIndexedAccess` in particular would
touch every array index and `Record` lookup in the app.

`TeamSection.vue` is only reachable by `vue-tsc`, which this app does
not run yet (that arrives in #15284). It is fixed here anyway so the
flag stays clean once that lands.

## Verification

`astro check` 0 errors with the flags on · 422 unit tests passing (1
pre-existing `minimaxMusic3` failure, also on `main`) · production build
595 pages · oxfmt clean.

Confirmed the new flags introduce no `vue-tsc` regressions: `vue-tsc`
reports the same 9 pre-existing SFC errors as `main` (same four files,
same counts — those are what #15282/#15283 fix), and **zero**
TS6133/TS6196/TS7027/TS7030 diagnostics, i.e. none attributable to these
flags. This PR is therefore independent of that stack and can merge in
any order relative to it.

---------

Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:R1 PR risk grade (advisory shadow check; grader-owned) size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants