Skip to content

Remove more as any casts with behaviour-preserving changes - #100419

Draft
jamiboym wants to merge 1 commit into
claude/as-any-type-onlyfrom
claude/as-any-equivalent-runtime
Draft

jamiboym wants to merge 1 commit into
claude/as-any-type-onlyfrom
claude/as-any-equivalent-runtime

Conversation

@jamiboym

Copy link
Copy Markdown
Contributor

Stacked on #100418 (type-only changes). Review that one first; this PR's diff is only the second commit.

Summary

Removes another ~156 as any casts: 62 in packages/next/src (153 → 91) and ~94 in tests. Unlike the previous PR, some of these change runtime code. Each one still behaves identically for every input, including null/primitives, Proxies, setters, frozen objects, this binding and evaluation order. Rewrites that only differ in edge cases (in checks, new null guards, ?., coercions) are deliberately left out.

Tests

  • Read isNextDev / isNextDeploy / isNextStart from e2e-utils instead of (global as any). nextTestSetup() returns getters for the same exports.
  • The global is true | undefined and the export is a boolean. Every use is in a boolean context (if, !, ternaries, defaulted params), so the two are interchangeable.
  • next-test-utils keeps its global read: it is also loaded without e2e-utils, and importing that module would run its side effects.

packages/next

  • Object.assign(target, { k: v }) instead of a cast plus property assignment, with the same [[Set]], the same order and the same strict-mode throw behaviour. This covers:
    • babel parse errors
    • the prerender-interrupted and bubbled base-server errors
    • _ogBody
    • the resolved IO promise
    • the redirect error's handled flag
    • the telemetry response
    • NEXT_BUILTIN_DOCUMENT
    • the sandbox router context
  • Small typed helpers with identical calls: inLayerGroup, excludesFalse, and a type-predicate arrow for .filter(Boolean).
  • Typed .call/.apply for the process and crypto patches in node-environment-extensions; this and arguments pass through unchanged.
  • Removes the unused future plumbing from the webpack config context; nothing reads ctx.future.
  • A few type-only leftovers:
    • overloads for resolveAsArrayOrUndefined
    • an internal __appRouter marker on CompletePrivateRouteInfo
    • a nullable dev-only WeakMap in use-action-queue
    • dropped casts in headers.test.ts / request-cookies.test.ts, now that the sealed types declare those methods

Verification

  • Wrote an equivalence argument for each runtime change. The commit message summarises them.
  • tsc --noEmit for packages/next and for the root project (tests). The root check's only errors are next/dist resolution misses in untouched tests, because the local worktree has no build.
  • Colocated jest suites for touched files, plus test/unit incremental-cache / sandbox / webpack-config suites. All pass except the 2 fast-set-immediate.external.test.ts tests that also fail on canary locally.
  • Not run: e2e suites touched by the isNextX swap (e.g. app-static, middleware-general, prerender), which need a full build; relying on CI.

Remove another 158 `as any` casts (62 in packages/next/src, 96 in
tests). Some changes here are runtime code, but each one behaves
identically for every input, including null/primitives, Proxies,
setters, frozen objects, `this` binding and evaluation order. `in`
checks, new null guards, `?.` and coercions are deliberately not used,
because they behave differently in edge cases.

Tests:
- Read `isNextDev`/`isNextDeploy`/`isNextStart` from `e2e-utils`
  instead of `(global as any)`. `nextTestSetup()` returns getters for the
  same exports. The global is `true | undefined` while the export is a
  boolean; every use is in a boolean context (`if`, `!`, ternaries,
  defaulted params), so this is equivalent. `next-test-utils` keeps the
  global read because it is also used without `e2e-utils`, and importing
  that would run its side effects.

packages/next:
- `Object.assign(target, { k: v })` instead of casting and assigning:
  same [[Set]], same order, same throw-on-failure in strict mode (babel
  parse errors, prerender-interrupted error, bubbled base-server error,
  `_ogBody`, resolved IO promise, redirect error `handled`, telemetry
  response, `NEXT_BUILTIN_DOCUMENT`, sandbox router context).
- Small typed helpers with identical calls: `inLayerGroup`,
  `excludesFalse` and a type-predicate arrow for `.filter(Boolean)`.
- Typed `.call`/`.apply` for the process and crypto patches in
  node-environment-extensions; `this` and `arguments` pass through
  unchanged.
- Delete the unused `future` plumbing from the webpack config context;
  nothing reads `ctx.future`.
- Type-only leftovers: overloads for `resolveAsArrayOrUndefined`, an
  internal `__appRouter` marker on `CompletePrivateRouteInfo`, a nullable
  dev-only WeakMap in `use-action-queue`, and dropping casts in
  `headers.test.ts`/`request-cookies.test.ts` now that the sealed types
  declare those methods.
@github-actions github-actions Bot added Font (next/font) Related to Next.js Font Optimization. tests type: next labels Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Failing test suites

Commit: 6dea1a6 | About building and testing Next.js

pnpm test-deploy test/e2e/app-dir/app-static/app-static.test.ts (job)

  • app-dir static/dynamic handling > should cache correctly handle JSON body (DD)
Expand output

● app-dir static/dynamic handling › should cache correctly handle JSON body

thrown: "Exceeded timeout of 60000 ms for a test.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

  571 |           gatedBodies.has(callback)
  572 |         ) {
> 573 |           return Reflect.apply(target, thisArg, args)
      |                          ^
  574 |         }
  575 |
  576 |         const applicable = [...describeGateStack]

  at Object.apply (lib/gate/runtime.ts:573:26)
  at Object.apply (lib/e2e-utils/index.ts:66:30)
  at it (e2e/app-dir/app-static/app-static.test.ts:4459:3)
  at Object.describe (e2e/app-dir/app-static/app-static.test.ts:18:1)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Font (next/font) Related to Next.js Font Optimization. tests type: next

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant