From 7fcb28820c77c99b94e18d808e53a1e9c5c8f867 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 05:41:08 +0000 Subject: [PATCH 1/2] test(core): drop the 10 redundant `$filter` casts in ValueDataSource.test.ts The `as any` on each of the ten AST-array `$filter` fixtures was written when `QueryParams.$filter` was declared as the MongoDB-style record alone. The slot now declares the union it always accepted, so the array literals assign bare. No runtime assertion is touched and no replacement assertion is introduced; the values were already legal, so they are written bare. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49 --- .../__tests__/ValueDataSource.test.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core/src/adapters/__tests__/ValueDataSource.test.ts b/packages/core/src/adapters/__tests__/ValueDataSource.test.ts index d03fa188ad..4430019ea7 100644 --- a/packages/core/src/adapters/__tests__/ValueDataSource.test.ts +++ b/packages/core/src/adapters/__tests__/ValueDataSource.test.ts @@ -165,7 +165,7 @@ describe('ValueDataSource — AST filter', () => { it('should filter with simple AST equality condition', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['role', '=', 'admin'] as any, + $filter: ['role', '=', 'admin'], }); expect(result.data).toHaveLength(2); expect(result.data.every((r: any) => r.role === 'admin')).toBe(true); @@ -174,7 +174,7 @@ describe('ValueDataSource — AST filter', () => { it('should filter with AST "in" operator', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['role', 'in', ['admin', 'guest']] as any, + $filter: ['role', 'in', ['admin', 'guest']], }); expect(result.data).toHaveLength(3); }); @@ -182,7 +182,7 @@ describe('ValueDataSource — AST filter', () => { it('should filter with AST "and" logical operator', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['and', ['role', '=', 'admin'], ['age', '>', 30]] as any, + $filter: ['and', ['role', '=', 'admin'], ['age', '>', 30]], }); expect(result.data).toHaveLength(1); expect(result.data[0].name).toBe('Charlie'); @@ -191,7 +191,7 @@ describe('ValueDataSource — AST filter', () => { it('should filter with AST "or" logical operator', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['or', ['role', '=', 'guest'], ['name', '=', 'Alice']] as any, + $filter: ['or', ['role', '=', 'guest'], ['name', '=', 'Alice']], }); expect(result.data).toHaveLength(2); }); @@ -199,7 +199,7 @@ describe('ValueDataSource — AST filter', () => { it('should filter with AST "!=" operator', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['role', '!=', 'admin'] as any, + $filter: ['role', '!=', 'admin'], }); expect(result.data).toHaveLength(3); }); @@ -207,7 +207,7 @@ describe('ValueDataSource — AST filter', () => { it('should filter with AST "not in" operator', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['role', 'not in', ['admin', 'guest']] as any, + $filter: ['role', 'not in', ['admin', 'guest']], }); expect(result.data).toHaveLength(2); expect(result.data.every((r: any) => r.role === 'user')).toBe(true); @@ -216,7 +216,7 @@ describe('ValueDataSource — AST filter', () => { it('should filter with AST "contains" operator', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['name', 'contains', 'li'] as any, + $filter: ['name', 'contains', 'li'], }); expect(result.data).toHaveLength(2); // Alice, Charlie }); @@ -224,21 +224,21 @@ describe('ValueDataSource — AST filter', () => { it('should filter with nested AST (and with in operator)', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['and', ['role', 'in', ['admin', 'user']], ['age', '>=', 28]] as any, + $filter: ['and', ['role', 'in', ['admin', 'user']], ['age', '>=', 28]], }); expect(result.data).toHaveLength(3); // Alice (30, admin), Charlie (35, admin), Diana (28, user) }); it('should return all items with empty AST filter', async () => { const ds = createDS(); - const result = await ds.find('users', { $filter: [] as any }); + const result = await ds.find('users', { $filter: [] }); expect(result.data).toHaveLength(5); }); it('should combine AST filter with sort', async () => { const ds = createDS(); const result = await ds.find('users', { - $filter: ['role', '=', 'admin'] as any, + $filter: ['role', '=', 'admin'], $orderby: { age: 'asc' }, }); expect(result.data).toHaveLength(2); From 234415d69a52056b95592ff35e7bd239ad4ed303 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 05:59:50 +0000 Subject: [PATCH 2/2] chore(changeset): declare the ValueDataSource cast removal as releasing nothing `scripts/check-changeset-presence.mjs` guards `packages/core/src/**`, and it answers a test-only change with the empty-frontmatter exemption rather than a carve-out. Gate run before: exit 1, naming this file. After: exit 0. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49 --- .../6001-drop-redundant-filter-casts.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .changeset/6001-drop-redundant-filter-casts.md diff --git a/.changeset/6001-drop-redundant-filter-casts.md b/.changeset/6001-drop-redundant-filter-casts.md new file mode 100644 index 0000000000..6598af17b3 --- /dev/null +++ b/.changeset/6001-drop-redundant-filter-casts.md @@ -0,0 +1,28 @@ +--- +--- + +Test-only change; nothing published changes. `ValueDataSource.test.ts` drops the ten +`as any` casts on its AST-array `$filter` fixtures +(`packages/core/src/adapters/__tests__/ValueDataSource.test.ts`, objectui#6001). + +The casts were written when `QueryParams.$filter` was declared as the MongoDB-style +record alone, so an author writing an ObjectQL AST array had to push the type out of the +way. objectui#3909 / PR objectui#5999 replaced that declaration with the union the data +sources always accepted, and all ten literals — the nine AST shapes plus the degenerate +empty array — now assign bare. No replacement assertion, no widening, no helper, and no +runtime assertion touched: `pnpm --filter @object-ui/core type-check` is green. + +One claim on the card did **not** survive measurement, and the correction is worth +keeping. The card justified the deletion partly by predicting that the un-cast fixtures +would become compile-time evidence — that narrowing `$filter` back to the record form +would turn this file red. It does not. Dropping the `| FilterArray` arm locally, +rebuilding `@object-ui/types` so the change reached the `dist/data.d.ts` that +`packages/core/tsconfig.test.json` actually resolves, and re-running the type-check +leaves the file green with zero errors — exactly as PR objectui#5999's own doc comment +says it must, since `Record` already accepts arrays structurally. A positive +control under the identical mutation (a slot that genuinely excludes arrays) does turn +these ten lines red, so the zero is a measurement rather than a blind apparatus. + +The deletion is therefore worth making for the smaller, true reason: `as any` at a site +where the value is already legal is a no-op that reads as a live constraint, and a reader +who trusts it concludes the array form is illegal here.