Skip to content

Conversation

@ajoslin
Copy link

@ajoslin ajoslin commented Feb 9, 2026

Hey, love Tanstack! here's a quick PR allowing separation of queryable/sortable types from returned types.

Summary

Problem: TanstackDB live query callbacks expose all model fields even when I want only allow a subset for filtering/sorting.

I return a lot of fields to the client from my API, using a query-backed collection with syncMode on demand. However, I don't want the client to be able to filter/sort by ALL of those fields, since not all of them can be efficiently queried on the backend.

The solution: add optional type-level queryable constraints so where/orderBy refs can be restricted while result rows remain full objects.

Non-invasive: additive typing only (querySchema + optional queryable/helper), defaults preserved, no runtime or planner behavior changes.

Example

type EngagementDocument = { // Returned from API, fully readable
  _id: string
  status: `ACTIVE` | `INACTIVE`
  user_id: string
  employer_id: string
  created_at: string
  updated_at: string
  platform_fee_percent: number
}
   createLiveQueryCollection({
      queryable: {
        filterable: [ // platform_fee_percent is NOT queryable!
          `_id`,
          `status`,
          `user_id`,
          `employer_id`,
          `created_at`,
          `updated_at`,
        ] as const,
        sortable: [`created_at`, `updated_at`, `status`] as const,
      },
      query: (q) =>
        q
          .from({ engagement: engagementsCollection })
          .where(({ engagement }) => {
            // @ts-expect-error platform_fee_percent is not queryable
            return eq(engagement.platform_fee_percent, 0.15)
          }),
    })

Allow where/orderBy refs to be constrained to policy-safe subsets while preserving full result model types and existing behavior when queryable is not configured.
@changeset-bot
Copy link

changeset-bot bot commented Feb 9, 2026

⚠️ No Changeset found

Latest commit: e296447

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@samwillis
Copy link
Collaborator

Hey @ajoslin

This looks interesting and I can see the real need for it.

Currently you are defining the queryable fields on the liveQueryCollection, not on the source collection. Would it be better to do it on the source collections so that they are not repeated?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants