Solid Query ist in TypeScript geschrieben, um sicherzustellen, dass die Bibliothek und Ihre Projekte typsicher sind!
Zu beachtende Punkte
Typen in Solid Query fließen im Allgemeinen sehr gut durch, sodass Sie keine Typannotationen für sich selbst bereitstellen müssen
import { useQuery } from '@tanstack/solid-query'
const query = useQuery(() => ({
queryKey: ['number'],
queryFn: () => Promise.resolve(5),
}))
query.data
// ^? (property) data: number | undefined
import { useQuery } from '@tanstack/solid-query'
const query = useQuery(() => ({
queryKey: ['number'],
queryFn: () => Promise.resolve(5),
}))
query.data
// ^? (property) data: number | undefined
import { useQuery } from '@tanstack/solid-query'
const query = useQuery(() => ({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
}))
query.data
// ^? (property) data: string | undefined
import { useQuery } from '@tanstack/solid-query'
const query = useQuery(() => ({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
}))
query.data
// ^? (property) data: string | undefined
Dies funktioniert am besten, wenn Ihre queryFn einen klar definierten Rückgabetyp hat. Beachten Sie, dass die meisten Datenabrufbibliotheken standardmäßig any zurückgeben, stellen Sie also sicher, dass Sie sie in eine ordnungsgemäß typisierte Funktion extrahieren
const fetchGroups = (): Promise<Group[]> =>
axios.get('/groups').then((response) => response.data)
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.data
// ^? (property) data: Group[] | undefined
const fetchGroups = (): Promise<Group[]> =>
axios.get('/groups').then((response) => response.data)
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.data
// ^? (property) data: Group[] | undefined
Solid Query verwendet einen diskriminierten Union-Typ für das Query-Ergebnis, der durch das Feld status und die abgeleiteten booleschen Statusflags diskriminiert wird. Dies ermöglicht es Ihnen, z. B. den success-Status zu prüfen, um data als definiert zu kennzeichnen
const query = useQuery(() => ({
queryKey: ['number'],
queryFn: () => Promise.resolve(5),
}))
if (query.isSuccess) {
const data = query.data
// ^? const data: number
}
const query = useQuery(() => ({
queryKey: ['number'],
queryFn: () => Promise.resolve(5),
}))
if (query.isSuccess) {
const data = query.data
// ^? const data: number
}
Der Typ für Fehler ist standardmäßig Error, da dies das ist, was die meisten Benutzer erwarten.
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: Error | null
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: Error | null
Wenn Sie einen benutzerdefinierten Fehler oder etwas werfen möchten, das kein Error ist, können Sie den Typ des Fehlerfelds angeben
const query = useQuery<Group[], string>(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: string | null
const query = useQuery<Group[], string>(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: string | null
Dies hat jedoch den Nachteil, dass die Typinferenz für alle anderen Generika von useQuery nicht mehr funktioniert. Es gilt im Allgemeinen nicht als gute Praxis, etwas anderes als einen Error auszulösen. Wenn Sie also eine Unterklasse wie AxiosError haben, können Sie Typ-Narrowing verwenden, um das Fehlerfeld spezifischer zu machen.
import axios from 'axios'
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: Error | null
if (axios.isAxiosError(query.error)) {
query.error
// ^? (property) error: AxiosError
}
import axios from 'axios'
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: Error | null
if (axios.isAxiosError(query.error)) {
query.error
// ^? (property) error: AxiosError
}
import '@tanstack/solid-query'
declare module '@tanstack/solid-query' {
interface Register {
// Use unknown so call sites must narrow explicitly.
defaultError: unknown
}
}
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: unknown | null
import '@tanstack/solid-query'
declare module '@tanstack/solid-query' {
interface Register {
// Use unknown so call sites must narrow explicitly.
defaultError: unknown
}
}
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: unknown | null
Ähnlich wie bei der Registrierung eines globalen Fehlertyps können Sie auch einen globalen Meta-Typ registrieren. Dies stellt sicher, dass das optionale Feld meta bei Queries und Mutationen konsistent und typsicher bleibt. Beachten Sie, dass der registrierte Typ von Record<string, unknown> erben muss, damit meta ein Objekt bleibt.
import '@tanstack/solid-query'
interface MyMeta extends Record<string, unknown> {
// Your meta type definition.
}
declare module '@tanstack/solid-query' {
interface Register {
queryMeta: MyMeta
mutationMeta: MyMeta
}
}
import '@tanstack/solid-query'
interface MyMeta extends Record<string, unknown> {
// Your meta type definition.
}
declare module '@tanstack/solid-query' {
interface Register {
queryMeta: MyMeta
mutationMeta: MyMeta
}
}
Wenn Sie Query-Optionen direkt in useQuery einfügen, erhalten Sie automatische Typschätzung. Möglicherweise möchten Sie die Query-Optionen jedoch in eine separate Funktion extrahieren, um sie zwischen useQuery und z. B. prefetchQuery zu teilen. In diesem Fall würden Sie die Typschätzung verlieren. Um sie wiederzugewinnen, können Sie den Helfer queryOptions verwenden
import { queryOptions } from '@tanstack/solid-query'
function groupOptions() {
return queryOptions({
queryKey: ['groups'],
queryFn: fetchGroups,
staleTime: 5 * 1000,
})
}
useQuery(groupOptions)
queryClient.prefetchQuery(groupOptions())
import { queryOptions } from '@tanstack/solid-query'
function groupOptions() {
return queryOptions({
queryKey: ['groups'],
queryFn: fetchGroups,
staleTime: 5 * 1000,
})
}
useQuery(groupOptions)
queryClient.prefetchQuery(groupOptions())
Darüber hinaus kennt der von queryOptions zurückgegebene queryKey die zugehörige queryFn, und wir können diese Typinformationen nutzen, um Funktionen wie queryClient.getQueryData ebenfalls typsicher zu machen
function groupOptions() {
return queryOptions({
queryKey: ['groups'],
queryFn: fetchGroups,
staleTime: 5 * 1000,
})
}
const data = queryClient.getQueryData(groupOptions().queryKey)
// ^? const data: Group[] | undefined
function groupOptions() {
return queryOptions({
queryKey: ['groups'],
queryFn: fetchGroups,
staleTime: 5 * 1000,
})
}
const data = queryClient.getQueryData(groupOptions().queryKey)
// ^? const data: Group[] | undefined
Ohne queryOptions wäre der Typ von data unknown, es sei denn, wir würden ihm ein generisches Element übergeben
const data = queryClient.getQueryData<Group[]>(['groups'])
const data = queryClient.getQueryData<Group[]>(['groups'])
Wenn Sie TypeScript verwenden, können Sie skipToken verwenden, um eine Abfrage zu deaktivieren. Dies ist nützlich, wenn Sie eine Abfrage basierend auf einer Bedingung deaktivieren möchten, aber die Abfrage trotzdem typsicher halten möchten.
Lesen Sie mehr darüber im Leitfaden Disabling Queries.