Describe the bug
.select() collapses discriminated union types on object fields into a single type with only the intersection of keys. Fields that are unique to individual union variants become inaccessible (never) in the result type, while the union is correctly preserved when no .select() is used.
To Reproduce
import { createCollection, createLiveQueryCollection } from '@tanstack/db'
type Document =
| { type: 'pdf'; url: string; pages: number }
| { type: 'image'; url: string; width: number; height: number }
| { type: 'legacy'; path: string }
type Item = { id: number; name: string; document: Document }
const items = createCollection<Item, number>({ id: 'items', getKey: (i) => i.id })
// ✅ Without .select() — union is preserved
const col1 = createLiveQueryCollection((q) => q.from({ i: items }))
col1.toArray[0]!.document // type: Document (correct union)
// ❌ With .select() — union is collapsed
const col2 = createLiveQueryCollection((q) =>
q.from({ i: items }).select(({ i }) => ({
id: i.id,
document: i.document,
})),
)
col2.toArray[0]!.document
// Actual type: { type: "pdf" | "image" | "legacy" }
// Variant-specific keys (url, pages, width, height, path) are lost
Expected behavior
result.document should have type Document (the original discriminated union) regardless of whether .select() is used. The union should be preserved so that narrowing (e.g., if (doc.type === 'pdf')) works correctly downstream.
Describe the bug
.select()collapses discriminated union types on object fields into a single type with only the intersection of keys. Fields that are unique to individual union variants become inaccessible (never) in the result type, while the union is correctly preserved when no.select()is used.To Reproduce
Expected behavior
result.documentshould have typeDocument(the original discriminated union) regardless of whether.select()is used. The union should be preserved so that narrowing (e.g.,if (doc.type === 'pdf')) works correctly downstream.