Repository navigation
fix(pypi): annotate top-30d map return so the null-filter narrows - #70
Merged
Merged
Conversation
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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
lib/integrations/pypi.tsfailstsc(and thereforenext build, which type-checks) with two cascading errors in the top-30d feed:.filter((x): x is FeedItem<PypiMeta> => x !== null)predicateconst items: FeedItem<PypiMeta>[] = …assignmentFeedItem.urlis optional (url?: string), but the feed built each item from an inline object literal closed withsatisfies FeedItem<PypiMeta>.satisfiespreserves the literal's narrow inferred type (url: string, required), which is structurally narrower thanFeedItem<PypiMeta>— so thex 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 asFeedItem<PypiMeta> | null— exactly how the siblingrssItemToFeedItem/huggingface/bluesky maps already type theirs — and drop the now-redundantsatisfies. 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