Skip to content

Per-API issues for the casts the cleanup deliberately left - #1590

Merged
sergey-shandar merged 6 commits into
claude/cast-type-annotations-refactor-hq8l8ofrom
claude/cast-followup-api-todos
Aug 15, 2026
Merged

Per-API issues for the casts the cleanup deliberately left#1590
sergey-shandar merged 6 commits into
claude/cast-type-annotations-refactor-hq8l8ofrom
claude/cast-followup-api-todos

Conversation

@sergey-shandar

Copy link
Copy Markdown
Contributor

Stacked on #1589 — its last commit is the diff to review here.

todo/inline-type-casts.md ends with 36 sites where the cast overrides a real type mismatch, and says each needs an issue against the API it papers over rather than a different cast syntax. This opens those issues for the 20 that share a cause, and records that the remaining one-offs do not.

New issue Sites What it is
fjs/effects/todo/do-generic-operation-signatures.md 3 Func<O> has nowhere to put a type parameter, so memCreate, memRead and all are cast while their non-generic neighbours in the same file are annotated declarations
fjs/effects/todo/step-continuation-operation-union.md 6 step/okStep continuations cast their way to the operation union the caller wants, which hides any operation the runner cannot interpret
fjs/effects/node/todo/async-operation-map-assignability.md 2 (+2 nearby) memoryOperationMap() is not assignable to ToAsyncOperationMap<O>
fjs/js/todo/token-kind-narrowing.md 4 keyword/operator collections typed over string, so has cannot narrow to a JsToken kind
fjs/types/btree/todo/find-path-item-typing.md 3 every tuple btree/find builds or indexes
fjs/emergent_testing/todo/mockrun-parameters-inference.md 2 Parameters<typeof mockRun<…>>[0] as an argument type

Two of these are worth reading past the summary. The ToAsyncOperationMap cast is the exact hazard fjs/AGENTS.md describes — a cast around a value handed to a generic parameter stops each handler being checked against O, so a drifted shape is absorbed rather than reported. The mockRun one has the same shape for the same reason.

The token-kind-narrowing issue also argues against the obvious fix: a type predicate would remove those four casts and AGENTS.md permits one where the alternative is a cast — but only where the predicate body is the structural check defining membership. A Set lookup asserting a union is not that, so the issue proposes typing the collection instead.

The audit doc gains a table linking all six, and states plainly that the remaining one-offs — a deliberately wrong value in a negative test, a nominal brand, FunctionNodeProgram — have no shared cause and are listed in the site table rather than given an issue each.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TQcZKuWSt2rEZrCj1jVZih


Generated by Claude Code

`todo/inline-type-casts.md` ends with 36 sites where the cast overrides a real
type mismatch, and says each needs an issue against the API it papers over
rather than a different cast syntax. This opens those issues for the 20 that
share a cause, and records that the remaining one-offs do not.

- `do_` has nowhere to put a type parameter, so the three generic effect
  constructors are cast while their non-generic neighbours in the same file are
  annotated declarations.
- Six `step`/`okStep` continuations cast their way to the operation union the
  caller wants, hiding any operation the runner cannot interpret.
- `memoryOperationMap()` is not assignable to `ToAsyncOperationMap<O>`, and that
  cast is the exact hazard AGENTS.md describes: it stops each handler being
  checked against `O`.
- Keyword and operator collections typed over `string` mean `has` cannot narrow
  to a `JsToken` kind, so four token constructions are cast.
- `btree/find` casts every tuple it builds or indexes.
- `mockRun`'s operation map reaches for `Parameters<typeof mockRun<…>>[0]`,
  which is what a call that cannot infer its type arguments looks like.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQcZKuWSt2rEZrCj1jVZih
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
functionalscript 6c6b12e Commit Preview URL

Branch Preview URL
Aug 15 2026, 07:01 PM

@o2alexanderfedin o2alexanderfedin left a comment

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.

Reviewed just 7338ce8 (the rest is #1589). Sites and arithmetic hold: 19 of the 20 cited casts exist verbatim at the cited file:line, the six per-issue counts sum to exactly 20, the audit table has exactly 36 "cast overrides" rows against 74 total matching the reason summary, nothing double-counted, all relative links resolve. Causes check out against source — Func<O> genuinely has no type-parameter slot and its neighbours really are annotated declarations; step's signature matches the quote verbatim; the ToAsyncOperationMap<O> passage says what's claimed. npm test → 2828 pass / 0 fail.

One inaccuracy, in fjs/js/todo/token-kind-narrowing.md: the stated cause — the collections holding those strings are typed over string — holds for the two djs sites (keywordSet is ReadonlySet<string>), but not for fjs/js/tokenizer/module.f.mjs:262. There keywords is /** @type {const} */, so kind already carries the literal union; the cast is needed because _KeywordToken excludes true/false/null/undefined as separate variants, so { kind } won't distribute over JsToken. Retyping the collection won't remove that cast, so "and the four casts go" overreaches.

Minor: fjs/cas/evo/module.f.mjs:456 is really 466 (inherited from #1589's table, not introduced here).

sergey-shandar and others added 5 commits August 15, 2026 11:47
…dant

`github-code-quality` flagged two unused variables in `types/nominal/proof`.
Following that up found the removals there had deleted the proof itself, and a
declaration-emit diff against `main` found four more removals that had changed
the published API. All ten type-checked; none were safe.

The API regressions, found by emitting `.d.mts` before and after:

- `effects/node` `createServer`: `<O extends Operation>(listener:
  RequestListener<O>) => Effect<O | CreateServer, Server>` became
  `(...payload: never) => Effect<Operation, never>`
- `effects/node` `log`/`error`: `Console` became the structural type
- `cas/evo` `emptyCache`: `Cache` became `{ bySubject: {} }`
- `types/range_map`: `RangeMapArray<T>` became `[T, number][]` — a purely
  functional library publishing a mutable array type

Three are now annotated declarations; `createServer` goes back to an inline
cast, which is what do-generic-operation-signatures.md is about.

`types/nominal/proof` demonstrates, per branding strategy, whether `<` compiles
between two branded values. The casts *are* the demonstration, and a brand is
unconstructible by design, so the declaration form rejects what the inline cast
accepted — `const a = {}` compared against `const b = {}` proves nothing. In a
proof about types the annotation is the test, and "does it still compile"
cannot see it being deleted.

Also clears the 36 `@import` entries the cleanup orphaned, so
`--noUnusedLocals` reports exactly what it did on `main`, and records both new
checks in the audit's method.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQcZKuWSt2rEZrCj1jVZih
# Conflicts:
#	todo/inline-type-casts.md
@sergey-shandar
sergey-shandar merged commit 88e8d79 into claude/cast-type-annotations-refactor-hq8l8o Aug 15, 2026
14 checks passed

@o2alexanderfedin o2alexanderfedin left a comment

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 fjs/cas/evo/module.f.mjs 456 → 466 reference is fixed (came in via the base branch).

The token-kind-narrowing.md point is still open — the file is byte-identical to 7338ce8; none of the new commits touch it. Re-proved it empirically this time: deleting the cast at fjs/js/tokenizer/module.f.mjs:262 gives TS2322 whose message shows kind is already the 49-member literal union, not string, and fails to distribute over _KeywordToken | _TrueToken | _FalseToken | _NullToken | _UndefinedToken. So retyping the collection won't remove that cast, and "the four casts go" still overreaches for that site.

Everything else in this PR's own content is unchanged and still correct: six new todos intact, links resolve, per-issue table still sums to 20. npm test → tsc clean, 2838 pass / 0 fail.

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.

3 participants