T
TanStack3d ago
adverse-sapphire

Defining and using an abstract collection type

A shared service used across apps expects an input of type Collection<T>, where T is a shared type definition of an object. The service uses the input collection to query and manipulate the underlying collection, while abstracting the logic of fetching and persisting data. The individual apps can supply any collection they like, as long as the items in that collection match T. How is this best achieved? When typing the input strictly as Collection<T>, I get various type issues, including the insert mutation transaction not propagating the row type. Instead it is typed as Record<string, any>
5 Replies
adverse-sapphire
adverse-sapphireOP2d ago
Downgrading between 0.5.3 to 0.5.2 has fixed the type issue that the item type does not propagate to mutation transactions. What would be the proper way to handle this is 0.5.3+?
xenial-black
xenial-black2d ago
You should specify at least the first two parameters: Collection<T, TKey> This ensures that: - transaction.mutations[0].modified stays typed as T - Insert/update/delete operations maintain proper types - No loss of type information to Record<string, any>
xenial-black
xenial-black2d ago
adverse-sapphire
adverse-sapphireOP2d ago
Thanks for the comprehensive reply!! My use case is slightly different, as the service knows ahead of time what type of collection to expect. See below a simplified version of my setup. In this function, transaction is typed as Transaction<Record<string, unknown>>, and therefore not usable for type inference downstream. As a solution, I now also return the created object itself, instead of retrieving it from the mutation.
type SessionCollection = Collection<Tables<'session'>, string>;
function startSession(sessions: SessionCollection) {
const newSession: Tables<'session'> = {} as Tables<'session'>;
const transaction = sessions.insert(newSession);
return { transaction, newSession };
}
type SessionCollection = Collection<Tables<'session'>, string>;
function startSession(sessions: SessionCollection) {
const newSession: Tables<'session'> = {} as Tables<'session'>;
const transaction = sessions.insert(newSession);
return { transaction, newSession };
}
the use case here is as follows: clients of the shared service provide different collections for the same data model, e.g. a local-first mobile app supplies the collection as an ElectricSQL collection, while the web app supplies it as a Tanstack Query collection.
xenial-black
xenial-black2d ago

Did you find this page helpful?