8000 fix(pypi): annotate top-30d map return so the null-filter narrows by aaronjmars · Pull Request #70 · aeonfun/minitor · GitHub
[go: up one dir, main page]

Skip to content

fix(pypi): annotate top-30d map return so the null-filter narrows - #70

Merged
aaronjmars merged 1 commit into
mainfrom
fix/pypi-feeditem-types
Jun 11, 2026
Merged

aaronjmars merged 1 commit into
mainfrom
fix/pypi-feeditem-types

Conversation

@aaronjmars
Copy link
Copy Markdown
Collaborator

Problem

lib/integrations/pypi.ts fails tsc (and therefore next build, which type-checks) with two cascading errors in the top-30d feed:

  • TS2677 at the .filter((x): x is FeedItem<PypiMeta> => x !== null) predicate
  • TS2322 at the const items: FeedItem<PypiMeta>[] = … assignment

FeedItem.url is optional (url?: string), but the feed built each item from an inline object literal closed with satisfies FeedItem<PypiMeta>. satisfies preserves the literal's narrow inferred type (url: string, required), which is structurally narrower than FeedItem<PypiMeta> — so the x is FeedItem<PypiMeta> predicate isn't assignable to the element type, and the null-filter stops narrowing.

This was pre-existing on main (untouched by the recent deck PRs); it just isn't caught because the repo has no typecheck/lint CI.

Fix

Annotate the .map() callback's return type as FeedItem<PypiMeta> | null — exactly how the sibling rssItemToFeedItem/huggingface/bluesky maps already type theirs — and drop the now-redundant satisfies. Two-line change.

Verification

  • npx tsc --noEmit → exit 0 (full project, previously failed only here)
  • npx eslint lib/integrations/pypi.ts → exit 0

🤖 Generated with Claude Code

The top-30d feed built each item from an inline object literal closed
with `satisfies FeedItem<PypiMeta>`. `satisfies` preserves the literal's
narrow inferred type (url: string, required), which is structurally
narrower than FeedItem<PypiMeta> (url?: string). That made the
`x is FeedItem<PypiMeta>` filter predicate invalid (TS2677) and the
items assignment fail (TS2322) — so `next build` (which runs tsc) broke.

Annotate the map callback's return type as `FeedItem<PypiMeta> | null`,
mirroring the sibling rss/huggingface/bluesky maps, and drop the now
redundant `satisfies`. Full project `tsc --noEmit` passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aaronjmars
aaronjmars merged commit 077277c into main Jun 11, 2026
1 check passed
@aaronjmars
aaronjmars deleted the fix/pypi-feeditem-types branch June 11, 2026 13:34
aaronjmars added a commit that referenced this pull request Jun 18, 2026
minitor had no CI. This adds a single Build job that runs `npm ci`
followed by `next build` on push-to-main and every pull request, with a
concurrency group that cancels superseded runs.

`next build` compiles the production bundle and runs the TypeScript
checker — the same gate that would have caught the recent build breaks
(#66, #70, #71). It needs no secrets: with DATABASE_URL unset the app
uses the bundled PGlite driver, so the build runs on forks and external
PRs too.

Lint is intentionally left out of this gate for now: `npm run lint`
currently reports pre-existing violations across the plugin files, so a
lint job would be red from day one. Worth a focused follow-up.

Co-authored-by: aaronjmars <aaronjmars@users.noreply.github.com>
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

0