Skip to content

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

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

fix: narrow several from any type assertions in opencode core#22926
kitlangton merged 1 commit intodevfrom
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 dev Apr 16, 2026
13 checks passed
@kitlangton kitlangton deleted the kit/unsafe-assertions branch April 16, 2026 21:15
Sign up for free to 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