Thore
Thore

Reputation: 1838

Handling undefined for returned data object from @tanstack/react-query's useQuery hook with TS linting rule 'strict' set to true

I'm working on a new project where the Typescript linting rule strict is set to true. With this rule, Typescript is no longer sure of the type of the returned data from the useQuery hook from the @tanstack/react-query package as it can be the actual type or undefined.

hooks/useFiles.ts

import { useQuery } from '@tanstack/react-query';
import { fileApi } from '@/utils/apiClient';
import { ListFileResponse } from '@types/files';

type useFilesProps = {
    page?: number;
    limit?: number;
};

export const useFiles = ({ page = 1, limit = 20 }: useFilesProps ) => {
    return useQuery<ListFileResponse>({
        queryKey: ['files'],
        queryFn: () => fileApi.listFiles({ page, limit }).then((res) => res.data),
    });
};

views/fileOverview.ts

export const FileOverview = () => {
    const { data: fileData } = useFiles({ page, limit });

    console.log(fileData);
    ...

Here fileData is ListFileResponse or undefined.

After adding checks for isLoading and isError I still get the same result.

const { data: fileData, isLoading: isFileLoading, isError: isFileError } = useFiles({ page, limit });

if (isFileLoading) return <p>Loading</p>;
if (isFileError) return <p>Error</p> ;

console.log(fileData);

What extra check do I have to do to make the TS linting convinced that fileData is not undefined?

Upvotes: 2

Views: 328

Answers (1)

Ro Milton
Ro Milton

Reputation: 2536

The reason TS doesn't narrow the type in your example is because you destructured the query object, and it can't keep track of the relationship any more.

To fix, don't destructure the query:

const filesQuery = useFiles({ page, limit });

if (!filesQuery.isSuccess) return <p>Something</p> ;

console.log(filesQuery.fileData); //TS knows this is not undefined now

Source: https://tkdodo.eu/blog/react-query-and-type-script#type-narrowing

Upvotes: 0

Related Questions