Typed context APIs to eliminate no-explicit-any in extension models
Opened by swampadmin · 10/11/2025
Problem Statement
Extension models that use context.dataRepository.getContent() are forced into pervasive // deno-lint-ignore no-explicit-any annotations because:
getContent()returnsUint8Array | null, requiring manualJSON.parse(new TextDecoder().decode(raw))which produces an untyped result- The parsed data must be cast
as anyto access properties like.accessories - Callback parameters in methods like
.find()on the parsed data need their ownanyannotations - Pairing data retrieved via
getContent()needsas anyto pass to typed functions likepairVerify()
In the @bixu/homekit extension, this results in 10+ lint-ignore comments across 3 methods, all stemming from the untyped getContent() return value. The deno fmt tool also moves as any casts to different lines than their lint-ignore comments, causing ban-unused-ignore errors that require additional workarounds.
Proposed Solution
Provide a typed readResource<T>() method on the context that:
- Accepts a resource spec name and instance name
- Returns the parsed, vault-resolved object typed against the spec's Zod schema
- Eliminates the need for manual JSON decode, vault resolution, and
as anycasts
This builds on #708 (add context.readResource()) and #709 (return parsed objects). The key addition here is that the return type should be inferred from the resource spec's Zod schema, so extension authors get type safety without casts.
Scope of changes:
- MethodContext: add generic
readResource<T>(specName, instanceName)that infers T from the spec schema - Data repository: handle JSON deserialization and vault expression resolution internally
- Extension model documentation: update examples to use the typed API
- This would eliminate the need for
as anycasts and their associated lint-ignore comments in well-structured extension models
Alternatives Considered
- Disable the
no-explicit-anylint rule in extension models — hides real type issues - Export helper functions for typed parsing — still requires manual wiring and doesn't integrate with vault resolution
- Use
z.infertypes manually — possible but verbose, and doesn't help with the getContent return type
Closed
No activity in this phase yet.
Sign in to post a ripple.