Skip to content

Commit bfea297

Browse files
KyleAMathewsclaude
andcommitted
fix: replace as-any casts with proper TemporalLike types
Address review feedback from Sam Willis and CodeRabbit: - Add TemporalLike interface in db-ivm for type-safe Temporal detection - Make isTemporal a proper type guard (returns input is TemporalLike) - Remove as-any casts in hashTemporal - Add return type to createTemporalLike test helper - Remove unnecessary casts in join regression test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7b6add2 commit bfea297

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

packages/db-ivm/src/hashing/hash.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@ const temporalTypes = new Set([
3131
`Temporal.ZonedDateTime`,
3232
])
3333

34-
function isTemporal(input: object): boolean {
35-
const tag = (input as any)[Symbol.toStringTag]
34+
interface TemporalLike {
35+
[Symbol.toStringTag]: string
36+
toString: () => string
37+
}
38+
39+
function isTemporal(input: object): input is TemporalLike {
40+
const tag = (input as Record<symbol, unknown>)[Symbol.toStringTag]
3641
return typeof tag === `string` && temporalTypes.has(tag)
3742
}
3843

@@ -122,11 +127,11 @@ function hashUint8Array(input: Uint8Array): number {
122127
return hasher.digest()
123128
}
124129

125-
function hashTemporal(input: object): number {
130+
function hashTemporal(input: TemporalLike): number {
126131
const hasher = new MurmurHashStream()
127132
hasher.update(TEMPORAL_MARKER)
128-
hasher.update((input as any)[Symbol.toStringTag])
129-
hasher.update((input as any).toString())
133+
hasher.update(input[Symbol.toStringTag])
134+
hasher.update(input.toString())
130135
return hasher.digest()
131136
}
132137

packages/db-ivm/tests/utils.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { hash } from '../src/hashing/index.js'
44

55
// Minimal mock that mimics Temporal objects: Symbol.toStringTag + toString()
66
// without requiring the temporal-polyfill dependency.
7-
function createTemporalLike(tag: string, value: string) {
7+
function createTemporalLike(
8+
tag: string,
9+
value: string,
10+
): { toString: () => string; [Symbol.toStringTag]: string } {
811
return Object.create(null, {
912
[Symbol.toStringTag]: { value: tag },
1013
toString: { value: () => value },

packages/db/src/utils.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,16 @@ const temporalTypes = new Set([
222222
`Temporal.ZonedDateTime`,
223223
])
224224

225+
export interface TemporalLike {
226+
[Symbol.toStringTag]: string
227+
toString: () => string
228+
equals?: (other: unknown) => boolean
229+
}
230+
225231
/** Checks if the value is a Temporal object by checking for the Temporal brand */
226-
export function isTemporal(a: any): boolean {
232+
export function isTemporal(a: unknown): a is TemporalLike {
227233
if (a == null || typeof a !== `object`) return false
228-
const tag = a[Symbol.toStringTag]
234+
const tag = (a as Record<symbol, unknown>)[Symbol.toStringTag]
229235
return typeof tag === `string` && temporalTypes.has(tag)
230236
}
231237

packages/db/tests/query/join.test.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,18 +2086,14 @@ function createJoinTests(autoIndex: `off` | `eager`): void {
20862086

20872087
await liveQuery.preload()
20882088
expect(liveQuery.toArray).toHaveLength(1)
2089-
expect(
2090-
(liveQuery.toArray[0]!.task.dueDate as Temporal.PlainDate).toString(),
2091-
).toBe(`2024-01-15`)
2089+
expect(String(liveQuery.toArray[0]!.task.dueDate)).toBe(`2024-01-15`)
20922090

2093-
taskCollection.update(1, (draft) => {
2094-
;(draft as any).dueDate = Temporal.PlainDate.from(`2024-06-15`)
2091+
taskCollection.update(1, (draft: Task) => {
2092+
draft.dueDate = Temporal.PlainDate.from(`2024-06-15`)
20952093
})
20962094
await flushPromises()
20972095

2098-
expect(
2099-
(liveQuery.toArray[0]!.task.dueDate as Temporal.PlainDate).toString(),
2100-
).toBe(`2024-06-15`)
2096+
expect(String(liveQuery.toArray[0]!.task.dueDate)).toBe(`2024-06-15`)
21012097
})
21022098
}
21032099

0 commit comments

Comments
 (0)