Skip to content

fix: narrow several from any type assertions in opencode core - #22926

Merged
kitlangton merged 1 commit into
devfrom
kit/unsafe-assertions
Apr 16, 2026
Merged

fix: narrow several from any type assertions in opencode core#22926
kitlangton merged 1 commit into
devfrom
kit/unsafe-assertions

Conversation

@kitlangton

Copy link
Copy Markdown
Contributor

Summary

First pass at the 107 "Unsafe assertion from any" sites flagged by oxlint's typescript/no-unsafe-type-assertion rule. These are the most dangerous casts because they silently launder untyped values into typed ones.

Strategy: focus on real laundering of any values, not inline-typed .json() as {...} patterns (lint still flags those, but they're fine — they annotate the expected API shape).

Not enabling the rule yet — this is a down payment on a larger cleanup.

Changes

  • util/filesystem.ts — change readJson<T = any> default to readJson<T = unknown>. Callers must now opt into a concrete type or handle unknown, which means a value parsed from a JSON file can't silently satisfy any shape.
  • npm/index.ts — add a PackageJson type for readJson so pkg.dependencies etc. are typed instead of any.
  • cli/cmd/tui/context/kv.tsx, test/config/config.test.ts — pass explicit type params to readJson at the call sites.
  • cli/error.ts — replace data?.suggestions as string[] | undefined and data?.issues as Array<...> with Array.isArray(...) ? ... : [] narrowing. Defensive: now behaves correctly (returns empty array) if the underlying error payload has the wrong shape.
  • lsp/lsp.ts — type client.connection.sendRequest<Symbol[]>("workspace/symbol", ...) and drop the intermediate as any annotations on the .then callbacks; return results.flat() directly instead of as Symbol[].
  • provider/provider.ts — narrow options?.workflowRef / options?.workflowDefinition via typeof === "string" instead of casting the values out of Record<string, any>.
  • session/session.ts — replace (... ?? 0) as number on the Anthropic/Bedrock/Vertex cache token fallback chain with Number(...) coercion. The existing safe() wrapper already handles NaN.
  • tool/tool.ts — change Context.extra from { [key: string]: any } to { [key: string]: unknown }. Downstream casts like ctx.extra?.promptOps as TaskPromptOps now become "more narrow" warnings instead of "from any" errors.

Impact

  • Unsafe assertion from any in opencode src: 29 → 25 (4 fixed).
  • Total no-unsafe-type-assertion across the repo: 1079 → 1073 errors.

Most of the remaining "from any" sites in opencode src are .json() as {...} inline-type annotations for fetch responses, which is a reasonable pattern the lint will always flag. Future passes could add runtime schema validation for the most critical ones (well-known config, model registries, etc.).

Verification

  • bun turbo typecheck passes (all 13 tasks).
  • bun run lint passes (oxlint warnings only, no errors).
  • bun test test/config/config.test.ts passes (73 tests, touches the updated readJson call).

Starting to address the 107 'Unsafe assertion from any' sites flagged by
oxlint's typescript/no-unsafe-type-assertion rule. Focused on real
laundering of any values into typed values, rather than inline-typed
`.json() as {...}` patterns (which the rule still flags but are fine).
- util/filesystem.ts: change `readJson<T = any>` default to `readJson<T = unknown>` so callers must opt into a type
- npm/index.ts: add PackageJson type for readJson callers
- cli/cmd/tui/context/kv.tsx, test/config/config.test.ts: pass explicit type params to readJson
- cli/error.ts: narrow `data?.suggestions` and `data?.issues` via Array.isArray instead of casting (defensive: preserves behavior when underlying error shape has wrong type)
- lsp/lsp.ts: type workspaceSymbol's sendRequest and drop intermediate `as any`s on .then callbacks
- provider/provider.ts: narrow options?.workflowRef / options?.workflowDefinition via typeof check rather than casting from Record<string, any>
- session/session.ts: use `Number(...)` coercion instead of `as number` on the Anthropic/Bedrock/Vertex cache token fallback chain (safe() already handles NaN)
- tool/tool.ts: change Context.extra from { [k: string]: any } to { [k: string]: unknown } \u2014 downstream casts become 'more narrow' (still warns but stops laundering any)
@kitlangton
kitlangton merged commit 23ed876 into devApr 16, 2026
13 checks passed
@kitlangton
kitlangton deleted the kit/unsafe-assertions branch April 16, 2026 21:15
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@kitlangton