boogiehsows
boogiehsows

Reputation: 163

Typescript useQuery Type

What would be the type which I have defined as any? I have tried TQueryFnData as per the RQ docs. but get Cannot find name 'TQueryFnData'

export const useFetchUser = (userID: string | undefined) => {
    return useQuery<any, Error>([users.fetchUser, userID],
        () => axios.get(`https://jsonplaceholder.typicode.com/users/${userID}`)
            .then(response => response.data))
}

An example of the data returned is: https://jsonplaceholder.typicode.com/users/1

export interface Users {
    id: number,
    name: string,
    username: string,
    email: string,
    address: Address,
    phone: string,
    website: string,
    company: Company
}

export interface Address {
  ...
}

export interface Geo {
  ...
}

export interface Company {
  ...
}

Upvotes: 2

Views: 22929

Answers (3)

Badal Saibo
Badal Saibo

Reputation: 3665

As the docs suggest, typing the fetcher function is the best way.

But for use-cases where you use a common fetcher function, Type Generics would be the go to way.

type ApiResponse<T> = {
  data: T;
  // You might want to include other properties like status, message, etc.
};

export const fetcher = async <T>({ queryKey: [url] }: QueryFunctionContext) => {
  if (typeof url === 'string') {
    return axiosInstance.get<ApiResponse<T>>(url).then((res) => res.data.data);
  }

  throw new Error('Invalid url provided');
};

Upvotes: 0

TkDodo
TkDodo

Reputation: 28733

As described in the docs and in my blog, the best thing you can do is make sure that your query function is typed to return a Promise of the type you'd expect. Then, you don't need to pass generics to useQuery at all.

There are many ways to achieve that:

  1. declare return type on the queryFn:
export const useFetchUser = (userID: string | undefined) => {
    return useQuery([users.fetchUser, userID],
        (): Promise<User> => axios.get(`https://jsonplaceholder.typicode.com/users/${userID}`)
            .then(response => response.data))
}
  1. declare a generic for axios.get:
export const useFetchUser = (userID: string | undefined) => {
    return useQuery([users.fetchUser, userID],
        () => axios.get<User>(`https://jsonplaceholder.typicode.com/users/${userID}`)
            .then(response => response.data))
}

Upvotes: 8

Besnik Kor&#231;a
Besnik Kor&#231;a

Reputation: 1094

Fix typo -

export interface Users
// to
export interface User

It is useQuery<Users, Error>

export const useFetchUser = (userID: string | undefined) => {
    return useQuery<User, Error>([users.fetchUser, userID],
        () => axios.get(`https://jsonplaceholder.typicode.com/users/${userID}`)
            .then(response => response.data))
}

Lastly here's a working example of your code on codesandbox

Upvotes: 3

Related Questions