Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-collection-compare-options-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/db": patch
---

Fix Collection compareOptions type error. This resolves a TypeScript error where collections created with `queryCollectionOptions()` (and other collection option functions) were incorrectly reported as missing the `compareOptions` property. The fix converts `compareOptions` from a getter to a public readonly property in the `CollectionImpl` class, ensuring proper type resolution with TypeScript's `Pick` utility.
9 changes: 2 additions & 7 deletions packages/db/src/collection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ export class CollectionImpl<
// and for debugging
public _state: CollectionStateManager<TOutput, TKey, TSchema, TInput>

private comparisonOpts: StringCollationConfig
public readonly compareOptions: StringCollationConfig

/**
* Creates a new Collection instance
Expand Down Expand Up @@ -270,7 +270,7 @@ export class CollectionImpl<
this._state = new CollectionStateManager(config)
this._sync = new CollectionSyncManager(config, this.id)

this.comparisonOpts = buildCompareOptionsFromConfig(config)
this.compareOptions = buildCompareOptionsFromConfig(config)

this._changes.setDeps({
collection: this, // Required for passing to CollectionSubscription
Expand Down Expand Up @@ -513,11 +513,6 @@ export class CollectionImpl<
return this._mutations.validateData(data, type, key)
}

get compareOptions(): StringCollationConfig {
// return a copy such that no one can mutate the internal comparison object
return { ...this.comparisonOpts }
}

/**
* Inserts one or more items into the collection
* @param items - Single item or array of items to insert
Expand Down
111 changes: 111 additions & 0 deletions packages/query-db-collection/tests/query.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { queryCollectionOptions } from "../src/query"
import type {
DeleteMutationFnParams,
InsertMutationFnParams,
StringCollationConfig,
UpdateMutationFnParams,
} from "@tanstack/db"

Expand Down Expand Up @@ -403,4 +404,114 @@ describe(`Query collection type resolution tests`, () => {
expectTypeOf(selectUserData).parameters.toEqualTypeOf<[ResponseType]>()
})
})

describe(`compareOptions property access`, () => {
it(`should have compareOptions property accessible on collection created with queryCollectionOptions`, () => {
type TodoType = {
id: string
title: string
completed: boolean
}

const options = queryCollectionOptions({
queryClient,
queryKey: [`todos`],
queryFn: async (): Promise<Array<TodoType>> => {
return [] as Array<TodoType>
},
getKey: (item) => item.id,
})

const collection = createCollection(options)

// This should not produce a type error - compareOptions should be accessible
expectTypeOf(
collection.compareOptions
).toEqualTypeOf<StringCollationConfig>()
})

it(`should have compareOptions property accessible when using schema`, () => {
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean(),
})

type TodoType = z.infer<typeof todoSchema>

const options = queryCollectionOptions({
queryClient,
queryKey: [`todos`],
queryFn: async (): Promise<Array<TodoType>> => {
return [] as Array<TodoType>
},
schema: todoSchema,
getKey: (item) => item.id,
})

const collection = createCollection(options)

// This should not produce a type error - compareOptions should be accessible
expectTypeOf(
collection.compareOptions
).toEqualTypeOf<StringCollationConfig>()
})

it(`should have compareOptions property accessible with schema transform`, () => {
// Reproduces the exact scenario from Discord bug report
const _schema = z
.object({
name: z.string().min(1),
})
.transform((item) => ({ ...item, id: -1, blubb: `blubb` }))

type SchemaOutput = z.infer<typeof _schema>

const options = queryCollectionOptions({
queryKey: [`local-test-array`],
// When using schema with transform, we need to provide the explicit type
queryFn: async (): Promise<Array<SchemaOutput>> => {
return [
{
name: `test`,
id: 0,
blubb: `blubb`,
},
]
},
getKey: (item) => item.id,
queryClient,
})

const collection = createCollection(options)

// This should not produce a type error - compareOptions should be accessible
// This was the exact error reported: "missing properties: comparisonOpts, compareOptions"
expectTypeOf(
collection.compareOptions
).toEqualTypeOf<StringCollationConfig>()
})

it(`should have compareOptions property accessible when using explicit type`, () => {
type TodoType = {
id: string
title: string
completed: boolean
}

const options = queryCollectionOptions<TodoType>({
queryClient,
queryKey: [`todos`],
queryFn: async () => [] as Array<TodoType>,
getKey: (item) => item.id,
})

const collection = createCollection(options)

// This should not produce a type error - compareOptions should be accessible
expectTypeOf(
collection.compareOptions
).toEqualTypeOf<StringCollationConfig>()
})
})
})
Loading