[PR #510] [MERGED] refactor: eliminate as any / as unknown as type assertions #632

Closed
opened 2026-05-06 13:09:12 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/510
Author: @james-elicx
Created: 3/12/2026
Status: Merged
Merged: 3/12/2026
Merged by: @james-elicx

Base: mainHead: opencode/proud-circuit


📝 Commits (2)

  • 67d67fe refactor: eliminate as any / as unknown as type assertions
  • d3a031b fix: restore typeof guards in restoreArrayBuffers to preserve original behaviour

📊 Changes

9 files changed (+161 additions, -79 deletions)

View changed files

📝 packages/vinext/src/check.ts (+9 -8)
📝 packages/vinext/src/cloudflare/kv-cache-handler.ts (+65 -25)
📝 packages/vinext/src/entries/pages-server-entry.ts (+9 -10)
📝 packages/vinext/src/global.d.ts (+17 -0)
📝 packages/vinext/src/index.ts (+2 -2)
📝 packages/vinext/src/shims/constants.ts (+1 -2)
📝 packages/vinext/src/shims/fetch-cache.ts (+28 -12)
📝 packages/vinext/src/shims/navigation.ts (+29 -19)
📝 packages/vinext/src/shims/router.ts (+1 -1)

📄 Description

Summary

Eliminates avoidable `as any` and `as unknown as` type assertions across the vinext codebase, replacing them with proper types, typed subclasses, and direct null-checks.

Changes

New types introduced

  • `ExtendedRequestInit` (`shims/fetch-cache.ts`) — `RequestInit & { _ogBody?: BodyInit; next?: unknown }` replaces 6 `(init as any)._ogBody` casts and 3 body duck-type-check casts
  • `VinextNavigationError` (`shims/navigation.ts`) — `class VinextNavigationError extends Error { readonly digest: string }` replaces 5 `(error as any).digest = ...` writes in `redirect`, `permanentRedirect`, `notFound`, `forbidden`, `unauthorized`
  • `SerializedIncrementalCacheValue` family (`cloudflare/kv-cache-handler.ts`) — parallel serialized types with `string` instead of `ArrayBuffer` for base64-encoded fields; removes ~10 `as any` casts from `serializeForJSON` / `restoreArrayBuffers`
  • `NodeJS.ProcessFeatures` augmentation (`global.d.ts`) — adds optional `typescript?: boolean` field, removing `(process.features as any)` in `shims/constants.ts`

Non-null assertions removed

  • `check.ts`: `pagesDir!`, `appDirPath!` → direct `!== null` checks; `importUsage.get(normalized)!` → local variable
  • `entries/pages-server-entry.ts`: `appFilePath!`, `docFilePath!` → direct `!== null` checks in ternary
  • `shims/router.ts`: `listeners.get(event)!` → explicit cast to `Set<...>`

Unnecessary `unknown` steps removed

  • `index.ts`: two `as unknown as ReadableStream` casts simplified to `as ReadableStream`
  • `shims/navigation.ts`: `null as unknown as typeof window.history.replaceState` → widened type `| null` + null guard

What was intentionally left alone

  • 13 `globalThis as unknown as Record<PropertyKey, unknown>` casts in `cache-runtime.ts` — TypeScript has no Symbol index signatures on `globalThis`; architecturally unavoidable
  • `window.NEXT_DATA` casts — `next.d.ts` declares `NEXT_DATA` without allowing augmentation; use-site cast is the only option
  • `(ctx as any).cacheControl?.revalidate` in `kv-cache-handler.ts` / `cache.ts` — `ctx` is typed `Record<string, unknown>` from the `CacheHandler` interface

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/510 **Author:** [@james-elicx](https://github.com/james-elicx) **Created:** 3/12/2026 **Status:** ✅ Merged **Merged:** 3/12/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `opencode/proud-circuit` --- ### 📝 Commits (2) - [`67d67fe`](https://github.com/cloudflare/vinext/commit/67d67fefc576fd392ef26dc8ecf3774e1ad89da1) refactor: eliminate as any / as unknown as type assertions - [`d3a031b`](https://github.com/cloudflare/vinext/commit/d3a031bb7e0a2ffc116a0a5adc0ed6390c36c4f7) fix: restore typeof guards in restoreArrayBuffers to preserve original behaviour ### 📊 Changes **9 files changed** (+161 additions, -79 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/check.ts` (+9 -8) 📝 `packages/vinext/src/cloudflare/kv-cache-handler.ts` (+65 -25) 📝 `packages/vinext/src/entries/pages-server-entry.ts` (+9 -10) 📝 `packages/vinext/src/global.d.ts` (+17 -0) 📝 `packages/vinext/src/index.ts` (+2 -2) 📝 `packages/vinext/src/shims/constants.ts` (+1 -2) 📝 `packages/vinext/src/shims/fetch-cache.ts` (+28 -12) 📝 `packages/vinext/src/shims/navigation.ts` (+29 -19) 📝 `packages/vinext/src/shims/router.ts` (+1 -1) </details> ### 📄 Description ## Summary Eliminates avoidable \`as any\` and \`as unknown as\` type assertions across the vinext codebase, replacing them with proper types, typed subclasses, and direct null-checks. ## Changes ### New types introduced - **\`ExtendedRequestInit\`** (\`shims/fetch-cache.ts\`) — \`RequestInit & { _ogBody?: BodyInit; next?: unknown }\` replaces 6 \`(init as any)._ogBody\` casts and 3 body duck-type-check casts - **\`VinextNavigationError\`** (\`shims/navigation.ts\`) — \`class VinextNavigationError extends Error { readonly digest: string }\` replaces 5 \`(error as any).digest = ...\` writes in \`redirect\`, \`permanentRedirect\`, \`notFound\`, \`forbidden\`, \`unauthorized\` - **\`SerializedIncrementalCacheValue\`** family (\`cloudflare/kv-cache-handler.ts\`) — parallel serialized types with \`string\` instead of \`ArrayBuffer\` for base64-encoded fields; removes ~10 \`as any\` casts from \`serializeForJSON\` / \`restoreArrayBuffers\` - **\`NodeJS.ProcessFeatures\` augmentation** (\`global.d.ts\`) — adds optional \`typescript?: boolean\` field, removing \`(process.features as any)\` in \`shims/constants.ts\` ### Non-null assertions removed - \`check.ts\`: \`pagesDir!\`, \`appDirPath!\` → direct \`!== null\` checks; \`importUsage.get(normalized)!\` → local variable - \`entries/pages-server-entry.ts\`: \`appFilePath!\`, \`docFilePath!\` → direct \`!== null\` checks in ternary - \`shims/router.ts\`: \`listeners.get(event)!\` → explicit cast to \`Set<...>\` ### Unnecessary \`unknown\` steps removed - \`index.ts\`: two \`as unknown as ReadableStream\` casts simplified to \`as ReadableStream\` - \`shims/navigation.ts\`: \`null as unknown as typeof window.history.replaceState\` → widened type \`| null\` + null guard ## What was intentionally left alone - 13 \`globalThis as unknown as Record<PropertyKey, unknown>\` casts in \`cache-runtime.ts\` — TypeScript has no Symbol index signatures on \`globalThis\`; architecturally unavoidable - \`window.__NEXT_DATA__\` casts — \`next.d.ts\` declares \`NEXT_DATA\` without allowing augmentation; use-site cast is the only option - \`(ctx as any).cacheControl?.revalidate\` in \`kv-cache-handler.ts\` / \`cache.ts\` — \`ctx\` is typed \`Record<string, unknown>\` from the \`CacheHandler\` interface --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:09:12 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#632
No description provided.