T
TanStack3y ago
foreign-sapphire

Custom useQuery Typesafe

Hi guys, I have a custom hook that wraps useQuery like this:
type DataError = {
isLoading: false;
isError: true;
data: undefined;
};

type DataLoading = {
isLoading: true;
isError: false;
data: undefined;
};

type DataSuccess = {
isLoading: false;
isError: false;
message: string;
};

type DataResult = DataError | DataLoading | DataSuccess;

const useUser = () => {
return useQuery({
queryKey: ['user'],
queryFn: () => {
return { id: '123', name: 'test' };
},
});
};

const useUserData = (): DataResult => {
const { data, isLoading, isError } = useUser();

return useMemo(() => {
if (isError) {
return { isLoading, isError, data: undefined };
}

if (isLoading) {
return { isLoading, isError, data: undefined };
}

return {
isLoading: false,
isError: false,
message: `It's user ${data.name}!`,
};
}, [data, isError, isLoading]);
};
type DataError = {
isLoading: false;
isError: true;
data: undefined;
};

type DataLoading = {
isLoading: true;
isError: false;
data: undefined;
};

type DataSuccess = {
isLoading: false;
isError: false;
message: string;
};

type DataResult = DataError | DataLoading | DataSuccess;

const useUser = () => {
return useQuery({
queryKey: ['user'],
queryFn: () => {
return { id: '123', name: 'test' };
},
});
};

const useUserData = (): DataResult => {
const { data, isLoading, isError } = useUser();

return useMemo(() => {
if (isError) {
return { isLoading, isError, data: undefined };
}

if (isLoading) {
return { isLoading, isError, data: undefined };
}

return {
isLoading: false,
isError: false,
message: `It's user ${data.name}!`,
};
}, [data, isError, isLoading]);
};
The useUserData hook relies on the result of useUser, but I want to maintain isLoading and isError states for component usage. Is there a better or more straightforward way to achieve this functionality ?
1 Reply
manual-pink
manual-pink3y ago
type inference
const useUserData = () => { ... }
const useUserData = () => { ... }
additionally, you can use satisfies DataResult at the end to adhere to an interface but still get type inference

Did you find this page helpful?