When a collection is created with .findOne(), it's typed as Collection<T> & SingleResult, correctly indicating it returns at most one row. However, when this collection is passed to queryOnce, the SingleResult information is lost:
// Collection correctly typed as SingleResult
const collection = createLiveQueryCollection({
query: (q) => q.from({ users }).where(...).findOne(),
}); // Collection<User> & SingleResult
// queryOnce wraps it in q.from(), losing SingleResult - returns User[] instead of User | undefined
const result = await queryOnce((q) => q.from({ user: collection }));
// ^? User[] — have to destructure: const [user] = result
Expected behavior:
queryOnce should either:
- Accept a
SingleResult collection directly and return Promise<T | undefined>, or
- Preserve the
SingleResult marker through q.from() so InferResultType returns T | undefined instead of T[]
Current workaround:
const [result] = await queryOnce((q) =>
q.from({ config: singleResultCollection }),
);
This works but loses type safety - result is typed as T | undefined only because of array destructuring, not because the type system knows it's a single-result query.
When a collection is created with
.findOne(), it's typed asCollection<T> & SingleResult, correctly indicating it returns at most one row. However, when this collection is passed toqueryOnce, theSingleResultinformation is lost:Expected behavior:
queryOnceshould either:SingleResultcollection directly and returnPromise<T | undefined>, orSingleResultmarker throughq.from()soInferResultTypereturnsT | undefinedinstead ofT[]Current workaround:
This works but loses type safety - result is typed as
T | undefinedonly because of array destructuring, not because the type system knows it's a single-result query.