TanStack / TanStack/db

persistedCollectionOptions: schema type parameter not inferred, result incompatible with createCollection

Open Beginner friendly
#1,452 1 comment 8 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
3.9k
Forks
266
Avg merge
1d 4h
Merged PRs (30d)
55

Description

  • I've validated the bug against the latest version of DB packages

Describe the bug

When passing a schema to persistedCollectionOptions, TypeScript fails to infer the TSchema type parameter. This causes two problems:

  1. Schema type not inferred: options.schema resolves to undefined instead of the actual schema type (e.g. a Zod schema). TSchema defaults to never.
  2. Incompatible with createCollection: The result cannot be passed to createCollection because:
    • createCollection's schema overloads require { schema: T } (required)
    • createCollection's no-schema overloads require { schema?: never }
    • The result has schema?: TSchema | undefined (optional), which matches neither

Root cause

persistedCollectionOptions lacks schema-aware overloads. Compare with localOnlyCollectionOptions (which works correctly) — it has separate overloads for the schema and no-schema cases with & { schema: T } / & { schema?: never } on both input and output types.

persistedCollectionOptions only has two overloads (sync-present vs sync-absent), neither of which distinguishes the schema case.

To Reproduce

import { z } from 'zod'
import { createCollection } from '@tanstack/db'
import { persistedCollectionOptions } from '@tanstack/db-sqlite-persistence-core'

const todoSchema = z.object({
  id: z.string(),
  title: z.string(),
})

const adapter = {
  loadSubset: () => Promise.resolve([]),
  applyCommittedTx: () => Promise.resolve(),
  ensureIndex: () => Promise.resolve(),
}

// TSchema defaults to `never` — schema type is lost
const options = persistedCollectionOptions({
  id: 'test',
  schema: todoSchema,
  schemaVersion: 1,
  getKey: (item) => item.id,
  persistence: { adapter },
})

// options.schema is `undefined` instead of `typeof todoSchema`

// This errors: "No overload matches this call"
const collection = createCollection(options)

Expected behavior

persistedCollectionOptions should infer the schema type and produce a result compatible with createCollection, matching the behavior of localOnlyCollectionOptions.

Additional context

The fix requires adding schema-aware overloads to persistedCollectionOptions (for both sync-present and sync-absent modes), following the same pattern used by localOnlyCollectionOptions in packages/db/src/local-only.ts.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at persistedCollectionOptions and compare its overloads with the schema-aware patterns in packages/db/src/local-only.ts. Verify both sync-present and sync-absent cases preserve the schema type and that the returned options can be passed to createCollection; done when the reproduction infers the schema and type-checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.