TypeScript
INFO
La fuente original (en ingles) de este tutorial se encuentra aquí
¡Vue Query ahora está escrito en TypeScript para garantizar que la biblioteca y sus proyectos sean seguros para escribir!
Cosas a tener en cuenta:
- Los tipos actualmente requieren el uso de TypeScript v4.7 o superior
- Los cambios en los tipos en este repositorio se consideran no disruptivos y generalmente se publican como cambios de parches de versionado semántico (de lo contrario, cada mejora de tipos sería una versión principal).
- Se recomienda encarecidamente que bloquee la versión de su paquete vue-query en una versión de parche específica y la actualice con la expectativa de que los tipos puedan corregirse o actualizarse entre cualquier versión.
- La API pública no relacionada con el tipo de Vue Query todavía sigue versionado semántico muy estrictamente.
Inferencia de Tipos
Los tipos en Vue Query generalmente fluyen muy bien, por lo que no es necesario que usted mismo proporcione anotaciones de tipo.
const { data } = useQuery({
// ^? const data: Ref<number> | Ref<undefined>
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
})
const { data } = useQuery({
// ^? const data: Ref<string> | Ref<undefined>
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
})
Esto funciona mejor si su queryFn
tiene un tipo devuelto bien definido. Tenga en cuenta que la mayoría de las bibliotecas de recuperación de datos devuelven any
de forma predeterminada, así que asegúrese de extraerlo en una función escrita correctamente:
const fetchGroups = (): Promise<Group[]> =>
axios.get('/groups').then((response) => response.data)
const { data } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const data: Ref<Group[]> | Ref<undefined>
Estrechamiento de Tipo
Vue Query utiliza un tipo de unión discriminada para el resultado de la consulta, discriminada por el campo status
y los indicadores status de estado derivados. Esto le permitirá comprobar, por ejemplo status de success
para definir data
:
const { data, isSuccess } = reactive(
useQuery({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
}),
)
if (isSuccess) {
data
// ^? const data: number
}
Tipar el Campo Error
El tipo de error predeterminado es Error
, porque eso es lo que la mayoría de los usuarios esperan.
const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const error: Error
const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const error: Ref<unknown>
if (error.value instanceof Error) {
error.value
// ^? const error: Error
}
const { error } = useQuery<Group[], string>(['groups'], fetchGroups)
// ^? const error: string | null
import axios from 'axios'
const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const error: Error | null
if (axios.isAxiosError(error)) {
error
// ^? const error: AxiosError
}
import '@tanstack/vue-query'
declare module '@tanstack/vue-query' {
interface Register {
defaultError: AxiosError
}
}
const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const error: AxiosError | null
Tipar meta Registrar Meta global
De manera similar a registrar un tipo de error global, también puede registrar un tipo Meta
global. Esto garantiza que el campo meta
opcional sobre consultas y mutaciones se mantenga coherente y tenga seguridad de escritura. Tenga en cuenta que el tipo registrado debe extender Record<string, unknown>
para que meta
siga siendo un objeto.
import '@tanstack/vue-query'
interface MyMeta extends Record<string, unknown> {
// Your meta type definition.
}
declare module '@tanstack/vue-query' {
interface Register {
queryMeta: MyMeta
mutationMeta: MyMeta
}
}
Tipar Opciones de Consultas
Si integra opciones de consulta en useQuery
, obtendrá una inferencia de tipos automática. Sin embargo, es posible que desee extraer las opciones de consulta en una función separada para compartirlas entre useQuery
y por ejemplo prefetchQuery
. En ese caso, perderías la inferencia de tipos. Para recuperarlo, puede utilizar el asistente queryOptions
:
import { queryOptions } from '@tanstack/vue-query'
function groupOptions() {
return queryOptions({
queryKey: ['groups'],
queryFn: fetchGroups,
staleTime: 5 * 1000,
})
}
useQuery(groupOptions())
queryClient.prefetchQuery(groupOptions())
Además, la queryKey
devuelta por queryOptions
conoce la queryFn
asociada a ella y podemos aprovechar esa información de tipo para que funciones como queryClient.getQueryData
también tengan en cuenta esos tipos:
function groupOptions() {
return queryOptions({
queryKey: ['groups'],
queryFn: fetchGroups,
staleTime: 5 * 1000,
})
}
const data = queryClient.getQueryData(groupOptions().queryKey)
// ^? const data: Group[] | undefined
Sin queryOptions
, el tipo de data
sería unknown
, a menos que le pasáramos un genérico:
const data = queryClient.getQueryData<Group[]>(['groups'])
Otras Lecturas
Para obtener consejos y trucos sobre la inferencia de tipos, consulte Vue Query y TypeScript en los recursos de la comunidad. Para saber cómo obtener la mejor seguridad de tipos posible, puede leer Vue Query con Tipos-seguros.
Desactivación segura de consultas mediante skipToken
Si está utilizando TypeScript, puede utilizar skipToken
para deshabilitar una consulta. Esto es útil cuando desea deshabilitar una consulta basada en una condición, pero aún desea mantener la consulta segura. Lea más al respecto en la guía Desactivación de Consultas.