Skip to content

fix(errors): replace chained cast on FACTORY_SYMBOL with typed property - #82

Open
martyy-code wants to merge 1 commit into
stagingfrom
fix/71-chained-cast-error-instance-marker
Open

fix(errors): replace chained cast on FACTORY_SYMBOL with typed property#82
martyy-code wants to merge 1 commit into
stagingfrom
fix/71-chained-cast-error-instance-marker

Conversation

@martyy-code

@martyy-code martyy-code commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Closes #71.

What

error.ts was assigning the factory marker via a chained type assertion:

(instance as unknown as Record<typeof FACTORY_SYMBOL, () => unknown>)[FACTORY_SYMBOL] = ErrorFactoryInstance;

This is the canonical example of the pattern rule 0008 forbids. The librarys own source was a counter-example to its own doctrine.

How

  • Move FACTORY_SYMBOL from error.ts (implementation) to types.ts (contract). The marker is part of the type — it belongs with the type.
  • Declare [FACTORY_SYMBOL]: ErrorFactory<TFields> on ErrorInstance<T>. The marker is now a typed property.
  • The assignment becomes a single property write on the declared type. The as unknown cast is gone.
  • is/index.ts updates its import to point at types.ts (where the symbol now lives).
  • Add a regression test confirming the marker is attached to a fresh instance and points back to the producing factory.

Verification

  • 83/83 tests pass (82 → 83, new regression).
  • pnpm type-check clean.
  • pnpm lint clean (run from the package dir).
  • Public API unchanged; the symbol is internal.

Note

The pre-commit eslint --fix hook is broken: it runs from the monorepo root and cannot find eslint.config.js (which only lives in packages/errors/). I committed with --no-verify after confirming the code passes prettier + eslint when run from the package dir. Worth a separate PR to fix the hook.

🤖 Generated with Claude Code

Issue #71: `error.ts` assigned the factory marker via a chained
type assertion `(instance as unknown as Record<typeof
FACTORY_SYMBOL, () => unknown>)[FACTORY_SYMBOL]` — the canonical
example of the pattern rule 0008 forbids.

Move `FACTORY_SYMBOL` from `error.ts` to `types.ts` (the
contract owns the marker, not the implementation) and declare it
as a typed property on `ErrorInstance<T>`. The assignment in
`error.ts` becomes a single property write on the declared
type; the `as unknown` cast is gone. `is/index.ts` updates its
import to match the new source.

Add a regression test in `error.test.ts` that confirms the
marker is attached to a fresh instance and points back to the
factory that produced it. Public API unchanged; all 83 tests
pass; type-check and lint clean.

Closes #71.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant