M7: Spec typing across KV, events and documents with expectTypeOf tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
This commit is contained in:
@@ -551,6 +551,21 @@ Decisions taken where the brief was silent. Each is the simplest option consiste
|
||||
- **Projections for non-KV event stores** must be passed explicitly (`projections: KVNode`); the
|
||||
projection key of a document is then `projections.prefix + docKey`.
|
||||
|
||||
### M7 — Types
|
||||
|
||||
- **`AnySpec` uses an index signature** (`{ [key: string]: AnySpec }`), not `Record<string, …>`, so
|
||||
`KeyOf<AnySpec>` is `string | number` and number keys type-check on untyped stores.
|
||||
- **`ChildOf` guards with `infer C extends Spec`** so that `KVNode<ChildOf<S, K>>` satisfies the `Spec`
|
||||
constraint generically.
|
||||
- **`setMany` entries are a union of precise `[key, value]` pairs** (`EntryOf<S>`), so on named levels a
|
||||
value must match its own key (`['age', 'x']` is rejected).
|
||||
- **Listings**: `keys()` yields `` `${KeyOf<S>}` `` (string literals on named levels, `string` on dynamic
|
||||
ones). `entries()` and `findBy()` yield `[string, V]` on dynamic levels.
|
||||
- **"Accept any node" parameters** are typed `KVNode<AnySpec>` / `EventNode<AnySpec>`. A typed node is
|
||||
assignable to these, but not to `KVNode<any>`, because `KeyOf<any>` collapses to `never`.
|
||||
- **Type tests** live in `test/types.test-d.ts` and are enforced by `tsc --noEmit` (part of `npm test`),
|
||||
including the `@ts-expect-error` negative cases from section 7.
|
||||
|
||||
<!-- decisions appended per milestone -->
|
||||
|
||||
## 13. Benchmark baselines
|
||||
|
||||
Reference in New Issue
Block a user