You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix: ensure module augmentation for ctx.meta is automatically loaded
Previously, the module augmentation for @tanstack/query-core that makes
ctx.meta?.loadSubsetOptions type-safe was in query.ts. This meant it wasn't
always processed by TypeScript unless something from that file was directly
imported.
This commit fixes the issue by:
1. Moving the module augmentation to a dedicated global.d.ts file
2. Adding a triple-slash reference in index.ts to ensure global.d.ts is
always loaded when the package is imported
3. Removing the duplicate module augmentation from query.ts
Now, ctx.meta?.loadSubsetOptions is automatically typed as LoadSubsetOptions
without requiring users to explicitly import QueryCollectionMeta or add any
manual type assertions.
Fixes the issue where users needed to use @ts-ignore or manual type assertions
to pass ctx.meta?.loadSubsetOptions to parseLoadSubsetOptions.
* fix: change QueryCollectionMeta to interface for proper extensibility
This commit addresses two critical issues identified in code review:
1. **Fixed double export**: Removed duplicate QueryCollectionMeta export from
the query.ts line in index.ts. QueryCollectionMeta is now only exported
from global.d.ts, which is its canonical source.
2. **Changed from type alias to interface**: Converting QueryCollectionMeta
from a type alias to an interface enables proper TypeScript declaration
merging. This allows users to extend meta with custom properties without
encountering "Subsequent property declarations must have the same type"
errors.
The updated documentation now shows the correct pattern for users to extend
meta:
```typescript
declare module "@tanstack/query-db-collection" {
interface QueryCollectionMeta {
myCustomProperty: string
}
}
```
This is safer than the previous pattern which would have caused users to
collide with the library's own Register.queryMeta augmentation.
Added a type test documenting the extension pattern for future reference.
* chore: run prettier on query.test-d.ts
* fix: resolve eslint errors in query-db-collection
- Replace triple-slash reference with import type {} from './global'
- Remove unused ExtendedMeta interface from test
All errors are now resolved, only pre-existing warnings remain.
* chore: add changeset for automatic meta type-safety
* docs: add section on extending meta with custom properties
Added comprehensive documentation explaining:
- Automatic type-safety for ctx.meta.loadSubsetOptions
- How to extend QueryCollectionMeta with custom properties via module augmentation
- Real-world examples including API request context
- Important notes about TypeScript declaration merging
This aligns with TanStack Query's official approach to typing meta using the Register interface.
* fix: ensure global.ts is emitted in build output
Changed global.d.ts to global.ts so TypeScript properly emits it as global.d.ts
in the dist folder. TypeScript's declaration emit only generates .d.ts files from
.ts source files - it does not copy handwritten .d.ts files to the output.
The module augmentation for @tanstack/query-core is now guaranteed to load because:
1. global.ts exports QueryCollectionMeta interface
2. index.ts re-exports it: export type { QueryCollectionMeta } from "./global"
3. When TypeScript processes the built index.d.ts, it must load global.d.ts to
resolve the export, which triggers processing of the module augmentation
This follows TypeScript best practices:
- Renamed .d.ts → .ts for proper build emission
- Re-export forces TypeScript to process the augmentation file
- No reliance on triple-slash references or side-effect imports
Updated comments to accurately reflect the mechanism.
---------
Co-authored-by: Claude <[email protected]>
fix: ensure ctx.meta.loadSubsetOptions type-safety works automatically
6
+
7
+
The module augmentation for ctx.meta.loadSubsetOptions is now guaranteed to load automatically when importing from @tanstack/query-db-collection. Previously, users needed to explicitly import QueryCollectionMeta or use @ts-ignore to pass ctx.meta?.loadSubsetOptions to parseLoadSubsetOptions.
8
+
9
+
Additionally, QueryCollectionMeta is now an interface (instead of a type alias), enabling users to safely extend meta with custom properties via declaration merging:
Copy file name to clipboardExpand all lines: docs/collections/query-collection.md
+120Lines changed: 120 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -77,6 +77,126 @@ The `queryCollectionOptions` function accepts the following options:
77
77
-`onUpdate`: Handler called before update operations
78
78
-`onDelete`: Handler called before delete operations
79
79
80
+
## Extending Meta with Custom Properties
81
+
82
+
The `meta` option allows you to pass additional metadata to your query function. By default, Query Collections automatically include `loadSubsetOptions` in the meta object, which contains filtering, sorting, and pagination options for on-demand queries.
83
+
84
+
### Type-Safe Meta Access
85
+
86
+
The `ctx.meta.loadSubsetOptions` property is automatically typed as `LoadSubsetOptions` without requiring any additional imports or type assertions:
// Pass custom meta alongside Query Collection defaults
143
+
meta: {
144
+
userId: "user-123",
145
+
includeDeleted: false,
146
+
},
147
+
})
148
+
)
149
+
```
150
+
151
+
### Important Notes
152
+
153
+
- The module augmentation pattern follows TanStack Query's official approach for typing meta
154
+
-`QueryCollectionMeta` is an interface (not a type alias), enabling proper TypeScript declaration merging
155
+
- Your custom properties are merged with the base `loadSubsetOptions` property
156
+
- All meta properties must be compatible with `Record<string, unknown>`
157
+
- The augmentation should be done in a file that's included in your TypeScript compilation
158
+
159
+
### Example: API Request Context
160
+
161
+
A common use case is passing request context to your query function:
162
+
163
+
```typescript
164
+
// types.d.ts
165
+
declaremodule"@tanstack/query-db-collection" {
166
+
interfaceQueryCollectionMeta {
167
+
authToken?:string
168
+
locale?:string
169
+
version?:string
170
+
}
171
+
}
172
+
173
+
// collections.ts
174
+
const productsCollection =createCollection(
175
+
queryCollectionOptions({
176
+
queryKey: ["products"],
177
+
queryFn: async (ctx) => {
178
+
const { loadSubsetOptions, authToken, locale, version } =ctx.meta
179
+
180
+
returnapi.getProducts({
181
+
...parseLoadSubsetOptions(loadSubsetOptions),
182
+
headers: {
183
+
Authorization: `Bearer ${authToken}`,
184
+
"Accept-Language": locale,
185
+
"API-Version": version,
186
+
},
187
+
})
188
+
},
189
+
queryClient,
190
+
getKey: (item) =>item.id,
191
+
meta: {
192
+
authToken: session.token,
193
+
locale: "en-US",
194
+
version: "v1",
195
+
},
196
+
})
197
+
)
198
+
```
199
+
80
200
## Persistence Handlers
81
201
82
202
You can define handlers that are called when mutations occur. These handlers can persist changes to your backend and control whether the query should refetch after the operation:
0 commit comments