Describe the bug
If you write a function that works on any Collection<T> (where T is a type parameter rather than a concrete type), the query builder's types break: inside where/join/select callbacks, the refs have no properties at all. Even properties that T's constraint guarantees (like id in T extends { id: string }) can't be accessed. This worked fine up to 0.6.5 and broke in 0.6.6.
The cause seems to be this type, added in 0.6.6 as part of unionAll (#1537):
type RefForContextValue<T, Nullable extends boolean = false> =
IsPlainObject<T> extends true ? Ref<T, Nullable> : RefLeaf<T, Nullable>;
When T is still an unresolved type parameter, TypeScript can't pick a side of that conditional (same for the IsNonExactOptional/IsNonExactNullable conditionals in RefsForContext), so the ref ends up as a union of every possible branch. One of those branches is RefLeaf, which has no row properties — and a union only exposes what all its members share, so the ref exposes nothing. Before 0.6.6, refs were always Ref<...>, so generic row types still worked.
To Reproduce
Typecheck this with tsc --strict against @tanstack/db 0.6.6 or later:
import { createLiveQueryCollection, eq, type Collection } from "@tanstack/db";
export function findById<T extends { id: string }>(items: Collection<T, string>, id: string) {
return createLiveQueryCollection((q) => q.from({ items }).where(({ items }) => eq(items.id, id)));
}
error TS2339: Property 'id' does not exist on type
'Ref<NonNullable<WithVirtualProps<T, string>>, true> | RefLeaf<NonNullable<WithVirtualProps<T, string>>, true> | ...'.
Property 'id' does not exist on type 'RefLeaf<NonNullable<WithVirtualProps<T, string>>, true>'.
The same root cause also breaks joins, though the error looks unrelated at first: using a subquery over a generic collection as a join source fails because its QueryBuilder<ContextFromSource<...>> no longer satisfies leftJoin's QueryBuilder<Context> parameter (the RefLeaf branch is missing the $synced/$origin/$key/$collectionId properties that every ref is required to have):
export 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, sub }) => eq(b.id, sub.id)); // TS2322 on `{ sub }`
});
}
Expected behavior
Both snippets compile, as they did on 0.6.5. A ref for a generic row type should expose at least the properties its constraint guarantees.
Desktop (please complete the following information):
@tanstack/db: broken in 0.6.6 through 0.6.14 (latest), works in 0.6.5
- TypeScript: 5.9.3 (
--strict)
- No browser/OS involved — this is compile-time only
Additional context
I tested every release from 0.6.5 through 0.6.14: 0.6.5 compiles, and every version from 0.6.6 onward fails. The Ref<T> distributivity change in 0.6.13 (#1597) changes the wording of the error but isn't where it started.
Describe the bug
If you write a function that works on any
Collection<T>(whereTis a type parameter rather than a concrete type), the query builder's types break: insidewhere/join/selectcallbacks, the refs have no properties at all. Even properties thatT's constraint guarantees (likeidinT extends { id: string }) can't be accessed. This worked fine up to 0.6.5 and broke in 0.6.6.The cause seems to be this type, added in 0.6.6 as part of
unionAll(#1537):When
Tis still an unresolved type parameter, TypeScript can't pick a side of that conditional (same for theIsNonExactOptional/IsNonExactNullableconditionals inRefsForContext), so the ref ends up as a union of every possible branch. One of those branches isRefLeaf, which has no row properties — and a union only exposes what all its members share, so the ref exposes nothing. Before 0.6.6, refs were alwaysRef<...>, so generic row types still worked.To Reproduce
Typecheck this with
tsc --strictagainst@tanstack/db0.6.6 or later:The same root cause also breaks joins, though the error looks unrelated at first: using a subquery over a generic collection as a join source fails because its
QueryBuilder<ContextFromSource<...>>no longer satisfiesleftJoin'sQueryBuilder<Context>parameter (theRefLeafbranch is missing the$synced/$origin/$key/$collectionIdproperties that every ref is required to have):Expected behavior
Both snippets compile, as they did on 0.6.5. A ref for a generic row type should expose at least the properties its constraint guarantees.
Desktop (please complete the following information):
@tanstack/db: broken in 0.6.6 through 0.6.14 (latest), works in 0.6.5--strict)Additional context
I tested every release from 0.6.5 through 0.6.14: 0.6.5 compiles, and every version from 0.6.6 onward fails. The
Ref<T>distributivity change in 0.6.13 (#1597) changes the wording of the error but isn't where it started.