From 6d14efa4c7694f051b28effc325299a636512c0b Mon Sep 17 00:00:00 2001 From: Benoit TRAVERS Date: Sun, 9 Aug 2026 11:41:03 +0200 Subject: [PATCH 1/2] test: sweep the redundant producer casts, keep one as the back-compat net PR #50 retyped computed's `from` callback and factory generators to the schema's `z.input`, making the `as z.infer` casts on their return values redundant. Sweeps them from the package's own spec and test-d files (docs and examples were already swept), leaving update() patch casts (PatchOf stays branded) and the one deliberate Legacy cast kept as a back-compat pin. --- packages/entity/src/base.spec.ts | 6 +++--- packages/entity/src/base.test-d.ts | 4 ++-- packages/entity/src/computed.spec.ts | 19 +++++-------------- packages/entity/src/contract.spec.ts | 5 +---- packages/entity/src/entity.test-d.ts | 17 +++++++++-------- packages/entity/src/nesting.spec.ts | 2 +- 6 files changed, 21 insertions(+), 32 deletions(-) diff --git a/packages/entity/src/base.spec.ts b/packages/entity/src/base.spec.ts index 2236354..ec1711c 100644 --- a/packages/entity/src/base.spec.ts +++ b/packages/entity/src/base.spec.ts @@ -13,7 +13,7 @@ abstract class AccountBase extends Entity.abstract("Account")( { immutable: ["id"], computed: { - shout: Entity.computed(Upper, (d) => d.label.toUpperCase() as z.infer), + shout: Entity.computed(Upper, (d) => d.label.toUpperCase()), }, invariants: [Entity.invariant((d) => d.label.length <= 20, "label must be at most 20 chars")], }, @@ -181,7 +181,7 @@ test("a variant declaring computed keeps the root's", () => { { note: Label }, { computed: { - murmur: Entity.computed(Label, (d) => d.label.toLowerCase() as z.infer), + murmur: Entity.computed(Label, (d) => d.label.toLowerCase()), }, }, ) { @@ -289,7 +289,7 @@ test("a variant redefining one computed key overrides that entry only", () => { { note: Label }, { computed: { - shout: Entity.computed(Upper, (d) => `${d.label}!`.toUpperCase() as z.infer), + shout: Entity.computed(Upper, (d) => `${d.label}!`.toUpperCase()), }, }, ) { diff --git a/packages/entity/src/base.test-d.ts b/packages/entity/src/base.test-d.ts index ce8603f..9fc7910 100644 --- a/packages/entity/src/base.test-d.ts +++ b/packages/entity/src/base.test-d.ts @@ -13,7 +13,7 @@ abstract class AccountBase extends Entity.abstract("Account")( { immutable: ["id"], computed: { - shout: Entity.computed(Upper, (d) => d.label.toUpperCase() as z.infer), + shout: Entity.computed(Upper, (d) => d.label.toUpperCase()), }, }, ) { @@ -119,7 +119,7 @@ test("a redefined computed key takes the variant's type, not an intersection", ( { note: Label }, { computed: { - shout: Entity.computed(Label, (d) => d.label.toLowerCase() as z.infer), + shout: Entity.computed(Label, (d) => d.label.toLowerCase()), }, }, ) { diff --git a/packages/entity/src/computed.spec.ts b/packages/entity/src/computed.spec.ts index 32f40b8..638ff90 100644 --- a/packages/entity/src/computed.spec.ts +++ b/packages/entity/src/computed.spec.ts @@ -14,14 +14,8 @@ class Person extends Entity("Person")( { immutable: ["id"], computed: { - fullName: Entity.computed( - FullName, - (d) => `${d.first} ${d.last}` as z.infer, - ), - initials: Entity.computed( - Initials, - (d) => `${d.first[0]}${d.last[0]}` as z.infer, - ), + fullName: Entity.computed(FullName, (d) => `${d.first} ${d.last}`), + initials: Entity.computed(Initials, (d) => `${d.first[0]}${d.last[0]}`), }, }, ) {} @@ -107,10 +101,7 @@ test("an invariant constrains a computed value through its sources", () => { { id: PersonId, first: NamePart, last: NamePart }, { computed: { - fullName: Entity.computed( - FullName, - (d) => `${d.first} ${d.last}` as z.infer, - ), + fullName: Entity.computed(FullName, (d) => `${d.first} ${d.last}`), }, invariants: [ Entity.invariant( @@ -137,7 +128,7 @@ test("computed output failing its own schema is a defect, not bad input", () => { // FullName requires at least 1 char; this returns an empty string computed: { - fullName: Entity.computed(FullName, () => "" as z.infer), + fullName: Entity.computed(FullName, () => ""), }, }, ) {} @@ -165,7 +156,7 @@ test("a defect names the field that produced it", () => { { id: PersonId, first: NamePart, last: NamePart }, { computed: { - initials: Entity.computed(Initials, () => "" as z.infer), + initials: Entity.computed(Initials, () => ""), }, }, ) {} diff --git a/packages/entity/src/contract.spec.ts b/packages/entity/src/contract.spec.ts index baf3f07..f9b7eb7 100644 --- a/packages/entity/src/contract.spec.ts +++ b/packages/entity/src/contract.spec.ts @@ -18,10 +18,7 @@ class ApiKey extends Entity("ApiKey")( // a denormalised field: stored so a query can index it, re-derived on // every construction so it cannot drift from `label` computed: { - searchKey: Entity.computed( - SearchKey, - (d) => d.label.toLowerCase() as z.infer, - ), + searchKey: Entity.computed(SearchKey, (d) => d.label.toLowerCase()), }, }, ) {} diff --git a/packages/entity/src/entity.test-d.ts b/packages/entity/src/entity.test-d.ts index 9c31054..e226689 100644 --- a/packages/entity/src/entity.test-d.ts +++ b/packages/entity/src/entity.test-d.ts @@ -127,7 +127,7 @@ test("an invariant sees the declared fields, never a computed one", () => { { id: OrgId, slug: Slug }, { computed: { - shout: Entity.computed(Upper, (d) => d.slug.toUpperCase() as z.infer), + shout: Entity.computed(Upper, (d) => d.slug.toUpperCase()), }, invariants: [ Entity.invariant((d) => { @@ -158,7 +158,7 @@ test("computed's function is contextually typed and must return brands", () => { // @ts-expect-error a plain string is not Upper const bad: { slugUpper: z.infer } = { slugUpper: "x" }; void bad; - return "X" as z.infer; + return "X"; }), }, }, @@ -196,10 +196,10 @@ test("factory generators are functions, and must cover exactly the generated fie ) {} // `as never` would defeat every assertion below — it is assignable to any - // type, including a function — so these use real branded values. - const id = "0199b1f4-1b1e-7000-8000-000000000000" as z.infer; - const at = "2026-08-06T09:00:00Z" as z.infer; - const slug = "s" as z.infer; + // type, including a function — so these use real values instead. + const id = "0199b1f4-1b1e-7000-8000-000000000000"; + const at = "2026-08-06T09:00:00Z"; + const slug = "s"; Org.factory({ id: () => id, createdAt: () => at }); @@ -224,7 +224,7 @@ test("a computed field is immutable without being declared immutable", () => { { id: OrgId, slug: Slug }, { computed: { - slugUpper: Entity.computed(Upper, (d) => d.slug.toUpperCase() as z.infer), + slugUpper: Entity.computed(Upper, (d) => d.slug.toUpperCase()), }, }, ) {} @@ -311,7 +311,8 @@ test("producers are castless: from and generators take the schema's input", () = ) {} void Wrong; - // back-compat: a branded (cast) return still assigns — brand ⊂ input + // Legacy: the one deliberate producer cast left in the repo, kept as the + // back-compat net — do not sweep it. class Legacy extends Entity("Legacy")( { id: StampId, name: Slug }, { diff --git a/packages/entity/src/nesting.spec.ts b/packages/entity/src/nesting.spec.ts index d4f178b..c2044e8 100644 --- a/packages/entity/src/nesting.spec.ts +++ b/packages/entity/src/nesting.spec.ts @@ -14,7 +14,7 @@ class Customer extends Entity("Customer")( { id: CustomerId, name: Name }, { computed: { - shout: Entity.computed(Upper, (d) => d.name.toUpperCase() as z.infer), + shout: Entity.computed(Upper, (d) => d.name.toUpperCase()), }, }, ) {} From cb4dd7c1eed49cb5fc122d883fb5074c16d575a0 Mon Sep 17 00:00:00 2001 From: Benoit TRAVERS Date: Sun, 9 Aug 2026 11:44:39 +0200 Subject: [PATCH 2/2] test: retitle the computed contextual-typing test to match its castless return Review flagged the old title as inaccurate after the cast sweep: the test's own final line (a castless return) demonstrates the opposite of "must return brands". --- packages/entity/src/entity.test-d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/entity/src/entity.test-d.ts b/packages/entity/src/entity.test-d.ts index e226689..9d547a7 100644 --- a/packages/entity/src/entity.test-d.ts +++ b/packages/entity/src/entity.test-d.ts @@ -143,7 +143,7 @@ test("an invariant sees the declared fields, never a computed one", () => { ); }); -test("computed's function is contextually typed and must return brands", () => { +test("computed's function is contextually typed over the declared fields, but its return needs no brand", () => { const Upper = z.string().brand("Upper"); Entity("Probe2")( { id: OrgId, slug: Slug },