Skip to content
Merged
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/generic-row-type-refs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/db': patch
---

Fix queries failing to typecheck when the collection's row type is a generic type parameter. Refs inside where/join/select callbacks now expose the properties guaranteed by the type parameter's constraint, and subqueries over generic collections can be used as join sources again (regression introduced in 0.6.6).
9 changes: 6 additions & 3 deletions packages/db/src/query/builder/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export type SchemaFromSource<T extends Source> = Prettify<{
[K in keyof T]: T[K] extends CollectionImpl<any, any, any, any, any>
? InferCollectionType<T[K]>
: T[K] extends QueryBuilder<infer TContext>
? GetResult<TContext>
? GetRawResult<TContext>
: never
}>

Expand Down Expand Up @@ -662,8 +662,11 @@ type ValueOfUnion<T, K extends PropertyKey> = T extends unknown
? T[K]
: never
: never
type RefForContextValue<T, Nullable extends boolean = false> =
IsPlainObject<T> extends true ? Ref<T, Nullable> : RefLeaf<T, Nullable>
type RefForContextValue<T, Nullable extends boolean = false> = T extends unknown
? IsPlainObject<T> extends true
? Ref<T, Nullable>
: RefLeaf<T, Nullable>
: never
type RefsSchemaForContext<TContext extends Context> =
IsExactlyUndefined<TContext[`refsSchema`]> extends true
? TContext[`schema`]
Expand Down
53 changes: 53 additions & 0 deletions packages/db/tests/query/generic-collection.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { describe, test } from 'vitest'
import { createLiveQueryCollection, eq } from '../../src/query/index.js'
import type { Collection } from '../../src/collection/index.js'

// Regression tests for https://github.com/TanStack/db/issues/1677
// Queries over a Collection<T> where T is an unresolved generic type parameter
// must still expose the properties guaranteed by T's constraint inside
// where/join/select callbacks. This worked in 0.6.5 and broke in 0.6.6.

describe(`queries over generic collection row types`, () => {
test(`where callback can access properties guaranteed by the type constraint`, () => {
function findById<T extends { id: string }>(
items: Collection<T, string>,
id: string,
) {
return createLiveQueryCollection((q) =>
q.from({ items }).where(({ items: itemsRef }) => eq(itemsRef.id, id)),
)
}

void findById
})

test(`select callback can access properties guaranteed by the type constraint`, () => {
function selectIds<T extends { id: string }>(items: Collection<T, string>) {
return createLiveQueryCollection((q) =>
q.from({ items }).select(({ items: itemsRef }) => ({
id: itemsRef.id,
})),
)
}

void selectIds
})

test(`subquery over a generic collection can be used as a join source`, () => {
function withDiff<T extends { id: string }>(
a: Collection<T, string>,
b: Collection<{ id: string }, string>,
) {
return createLiveQueryCollection((q) => {
const sub = q.from({ a })
return q
.from({ b })
.leftJoin({ sub }, ({ b: bRef, sub: subRef }) =>
eq(bRef.id, subRef.id),
)
})
}

void withDiff
})
})
Loading