Skip to content

fix(svelte-query): allow per-query persisters in createQuery#10885

Open
JetProc wants to merge 1 commit into
TanStack:mainfrom
JetProc:fix/svelte-query-createquery-persister
Open

fix(svelte-query): allow per-query persisters in createQuery#10885
JetProc wants to merge 1 commit into
TanStack:mainfrom
JetProc:fix/svelte-query-createquery-persister

Conversation

@JetProc
Copy link
Copy Markdown

@JetProc JetProc commented Jun 5, 2026

🎯 Changes

Closes #9729.

createQuery accepts the core query option surface through its Svelte accessor, but a query-level persister could participate in query key and data inference. That could make valid per-query persister values fail overload resolution or leave data inferred as unknown.

This keeps persister from driving CreateQueryOptions inference while leaving the runtime behavior unchanged. A type regression test covers passing a per-query persister directly to createQuery.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes
    • Fixed createQuery type definitions to support per-query persister configuration.

Query persisters are allowed as query options in core, but the Svelte createQuery accessor path let the persister type participate in query key and data inference. That could make a valid per-query persister reject overload resolution or leave result data as unknown.

This keeps the runtime path unchanged and limits the type relaxation to the createQuery option surface, with a regression test covering the reported usage.

Constraint: Match TanStack Query's Svelte package boundaries and keep the fix type-only

Rejected: Relax CreateBaseQueryOptions | it also affected internal defaultQueryOptions and infinite query typing

Confidence: high

Scope-risk: narrow

Directive: Keep queryFn as the source of createQuery result data inference when persister is present

Tested: pnpm run test:pr

Tested: corepack pnpm nx run @tanstack/svelte-query:test:types

Tested: corepack pnpm nx run @tanstack/svelte-query:test:lib

Tested: corepack pnpm nx run @tanstack/svelte-query:test:eslint

Tested: corepack pnpm nx run @tanstack/svelte-query:test:build
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR fixes the type definition for createQuery in @tanstack/svelte-query to allow per-query persister override. The CreateQueryOptions type now explicitly exposes persister as an optional property, and a type-level test validates the override behavior and type inference.

Changes

Per-query persister override support

Layer / File(s) Summary
Per-query persister type contract and validation
packages/svelte-query/src/types.ts, packages/svelte-query/tests/createQuery/createQuery.test-d.ts
QueryPersister type is imported and CreateQueryOptions is updated to explicitly define persister as optional, allowing per-query override. A type test validates that passing persister on individual createQuery calls preserves the expected query result type.
Release metadata
.changeset/svelte-query-persister-options.md
Changeset documents the patch bump and describes the fix to createQuery typings for per-query persister override.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes


A persister now hops through each query's own door, 🐰

No longer locked by defaults anymore!

Override with grace, type-safe and true,

Svelte queries do just what you want them to.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: fixing Svelte Query's createQuery to support per-query persisters. It directly summarizes the core objective.
Description check ✅ Passed The description includes the required sections (Changes, Checklist, Release Impact) with complete information. The author provided context, marked checklist items, and confirmed a changeset was generated.
Linked Issues check ✅ Passed The PR directly addresses issue #9729 by fixing type inference to allow per-query persisters in createQuery. The type changes enable valid persister values to pass type checking while maintaining runtime behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the persister typing in Svelte's createQuery. The changeset, type definition, and regression test are all focused on the stated objective with no extraneous modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@JetProc JetProc marked this pull request as ready for review June 5, 2026 08:52
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
packages/svelte-query/tests/createQuery/createQuery.test-d.ts (1)

11-25: ⚡ Quick win

Consider using the QueryPersister type directly for stronger type validation.

The test manually constructs a persister signature rather than using QueryPersister<string[], ['todos']> from @tanstack/query-core. While the hand-crafted signature validates the basic fix, using the actual QueryPersister type would ensure the test catches any subtle incompatibilities between the type definition in types.ts and real persister implementations.

♻️ Suggested refactor to use QueryPersister type
-    const persister = undefined as unknown as <T, TQueryKey extends QueryKey>(
-      queryFn: (context: QueryFunctionContext<TQueryKey>) => T | Promise<T>,
-      context: QueryFunctionContext<TQueryKey>,
-      query: Query,
-    ) => Promise<T>
+    const persister: QueryPersister<string[], ['todos']> = 
+      undefined as any

Alternatively, if you want to keep the generic formulation to test that the type accepts generic persisters:

+    import type { QueryPersister } from '`@tanstack/query-core`'
+
-    const persister = undefined as unknown as <T, TQueryKey extends QueryKey>(
-      queryFn: (context: QueryFunctionContext<TQueryKey>) => T | Promise<T>,
-      context: QueryFunctionContext<TQueryKey>,
-      query: Query,
-    ) => Promise<T>
+    const persister = undefined as unknown as QueryPersister<any, any>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/svelte-query/tests/createQuery/createQuery.test-d.ts` around lines
11 - 25, Replace the hand-constructed persister function type in the test with
the official QueryPersister type from `@tanstack/query-core` to ensure correct,
stronger type checking: import QueryPersister and declare persister as
QueryPersister<string[], ['todos']> (used in the createQuery call) so the test
validates real persister compatibility with createQuery and the types defined in
types.ts.
packages/svelte-query/src/types.ts (1)

45-50: ⚡ Quick win

Type safety trade-off: Svelte’s persister?: QueryPersister<any, any> erases persister/query coupling

packages/svelte-query/src/types.ts widens persister to QueryPersister<any, any>, which removes the type-level link between the persister’s queryFn (and key/pageParam expectations) and the query’s TQueryFnData/TQueryKey/TPageParam—so TypeScript won’t catch mismatches that query-core’s persister?: QueryPersister<TQueryFnData, NoInfer<TQueryKey>, TPageParam> would. The persister shape is still enforced, but its generic safety is effectively gone. Consider documenting this trade-off (and/or investigating a stricter alternative that preserves inference) since other query packages don’t appear to use the same QueryPersister<any, any> erasure.

export type CreateQueryOptions<...> = OmitKeyof<
  CreateBaseQueryOptions<...>,
  'persister'
> & {
  persister?: QueryPersister<any, any>
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/svelte-query/src/types.ts` around lines 45 - 50, The persister
generic is being erased by using QueryPersister<any, any> which loses the link
to the query's generics; update the CreateQueryOptions type in
packages/svelte-query/src/types.ts (the CreateQueryOptions and referenced
CreateBaseQueryOptions/persister entry) to preserve type coupling by typing
persister as QueryPersister<TQueryFnData, NoInfer<TQueryKey>, TPageParam> (or
the equivalent generic parameters used by query-core) instead of any, and
import/alias NoInfer if required; if preserving inference is not feasible, add a
concise code comment above CreateQueryOptions documenting this deliberate
trade-off and why the generics were widened.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/svelte-query/src/types.ts`:
- Around line 45-50: The persister generic is being erased by using
QueryPersister<any, any> which loses the link to the query's generics; update
the CreateQueryOptions type in packages/svelte-query/src/types.ts (the
CreateQueryOptions and referenced CreateBaseQueryOptions/persister entry) to
preserve type coupling by typing persister as QueryPersister<TQueryFnData,
NoInfer<TQueryKey>, TPageParam> (or the equivalent generic parameters used by
query-core) instead of any, and import/alias NoInfer if required; if preserving
inference is not feasible, add a concise code comment above CreateQueryOptions
documenting this deliberate trade-off and why the generics were widened.

In `@packages/svelte-query/tests/createQuery/createQuery.test-d.ts`:
- Around line 11-25: Replace the hand-constructed persister function type in the
test with the official QueryPersister type from `@tanstack/query-core` to ensure
correct, stronger type checking: import QueryPersister and declare persister as
QueryPersister<string[], ['todos']> (used in the createQuery call) so the test
validates real persister compatibility with createQuery and the types defined in
types.ts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 249ea428-b8d0-4657-961b-5aa46f920c61

📥 Commits

Reviewing files that changed from the base of the PR and between 3270e09 and f3f1ddc.

📒 Files selected for processing (3)
  • .changeset/svelte-query-persister-options.md
  • packages/svelte-query/src/types.ts
  • packages/svelte-query/tests/createQuery/createQuery.test-d.ts

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.

Svelte createQuery doesn't support passing in a persister properly

1 participant