Solid Query 使用 TypeScript 撰寫,以確保函式庫與您的專案具備型別安全性!
需注意的事項:
Solid Query 中的型別通常能良好流動,因此您無需自行提供型別註解
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
若您的 queryFn 有明確定義的回傳型別,此功能效果最佳。請注意,多數資料獲取函式庫預設回傳 any,因此請確保將其提取為具有正確型別的函式:
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 使用判別聯合型別 (discriminated union type) 作為查詢結果,以 status 欄位和衍生的狀態布林標誌進行判別。這讓您可以檢查例如 success 狀態,以確保 data 有定義:
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
}
錯誤的型別預設為 Error,因為這是多數使用者所預期的。
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
若您想拋出自訂錯誤,或根本不是 Error 的內容,您可以指定錯誤欄位的型別:
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
然而,這會導致 useQuery 的所有其他泛型型別推論失效。通常不建議拋出非 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 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
}
TanStack Query v5 允許透過擴充 Register 介面來設定全域錯誤型別,而無需在呼叫端指定泛型。這將確保型別推論仍有效,但錯誤欄位會是指定的型別:
import '@tanstack/solid-query'
declare module '@tanstack/solid-query' {
interface Register {
defaultError: AxiosError
}
}
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: AxiosError | null
import '@tanstack/solid-query'
declare module '@tanstack/solid-query' {
interface Register {
defaultError: AxiosError
}
}
const query = useQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
query.error
// ^? (property) error: AxiosError | null
類似於註冊全域錯誤型別,您也可以註冊全域 Meta 型別。這確保了查詢和變異上的選用 meta 欄位保持一致且具備型別安全性。請注意,註冊的型別必須擴展 Record<string, unknown>,以確保 meta 仍為物件。
import '@tanstack/solid-query'
interface MyMeta extends Record<string, unknown> {
// 您的 meta 型別定義。
}
declare module '@tanstack/solid-query' {
interface Register {
queryMeta: MyMeta
mutationMeta: MyMeta
}
}
import '@tanstack/solid-query'
interface MyMeta extends Record<string, unknown> {
// 您的 meta 型別定義。
}
declare module '@tanstack/solid-query' {
interface Register {
queryMeta: MyMeta
mutationMeta: MyMeta
}
}
若您將查詢選項內聯至 useQuery,您將獲得自動型別推論。然而,您可能希望將查詢選項提取至獨立的函式,以在 useQuery 和例如 prefetchQuery 之間共享。此時,您將失去型別推論。要重新獲得它,您可以使用 queryOptions 輔助函式:
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())
此外,queryOptions 回傳的 queryKey 知道與其關聯的 queryFn,我們可以利用此型別資訊讓例如 queryClient.getQueryData 等函式也能感知這些型別:
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
若沒有 queryOptions,data 的型別會是 unknown,除非我們傳遞泛型給它:
const data = queryClient.getQueryData<Group[]>(['groups'])
const data = queryClient.getQueryData<Group[]>(['groups'])
若您使用 TypeScript,可以使用 skipToken 停用查詢。這在您想根據條件停用查詢,但仍希望保持查詢的型別安全時非常有用。
更多資訊請參閱停用查詢指南。