基于函数内部数据获取状态(loading, loaded, error)的函数返回类型



沙箱链接:https://codesandbox.io/s/youthful-mclean-csm60i?file=/src/useFetch.ts

我的类型:

type TUseFetchLoadingState = {
loading: true;
data: never;
update: never;
mutate: never;
error: never;
};
type TUseFetchLoadedState<T> = {
data: T;
loading: never;
update: Dispatch<SetStateAction<T>>;
mutate: KeyedMutator<T>;
error: never;
};
type TUseFetchErrorState = {
error: AxiosError;
loading: never;
data: never;
update: never;
mutate: never;
};
type TUseFetchReturnType<T> = TUseFetchLoadingState | TUseFetchLoadedState<T> | TUseFetchErrorState;

钩:

const useFetch = <T>(url: string | null): TUseFetchReturnType<T> => {
const { data, error, mutate } = useSWR<T, AxiosError>(url ? url : null);
const [fetchedData, setFetchedData] = useState<T>();
useEffect(() => {
if (data) setFetchedData(data);
}, [data]);
if (!fetchedData && !error) {
return {
loading: true,
};
}
if (error) {
return {
error,
};
}
return {
data: fetchedData as T,
update: setFetchedData as Dispatch<SetStateAction<T>>,
mutate,
};
};

钩子的思想是,当我从服务器(服务器端状态)检索数据时,我将其存储在本地状态,以便我可以更改UI,而无需等待服务器端状态重新验证和更新UI。

我想正确地键入函数的返回类型,这样当没有数据和错误时,它的返回类型将是{ loading:true },以便稍后在组件中我可以进行typeguard。

...
if (!loading) { ... } // means there's either data or error
...
if (!error) { ... } // means no error, data fetched successfully

如果检索到的数据没有任何错误,则应该返回数据、数据设置器和mutator,以便立即重新验证服务器端状态。

当出现错误时,我只想返回error对象。

我希望它如何在组件中使用:

const MyComponent = () => {
const { data, update, loading, error, mutate } = useFetch(ENDPOINTS.SOME_ENDPOINT);

if (error) return <ErrorComponent error={error} />
if (loading) return <LoadingComponent />

// data is available, do something with it
return (
<Box>
{/*do something with data*/}
</Box>
);
}

我对props做了类似的操作

type RequiredTableToolbarProps = {
title: string;
};
type SelectableTableToolbarProps = RequiredTableToolbarProps & {
numSelected: number;
onDeleteSelected: () => void | Promise<void>;
};
type NonSelectableTableToolbarProps = RequiredTableToolbarProps & {
numSelected: never;
onDeleteSelected: never;
};
export type TableToolbarProps = SelectableTableToolbarProps | NonSelectableTableToolbarProps;

效果很好:要么组件同时有numSelectedonDeleteSelected,要么没有。

我怎么能做同样的事情与函数返回类型?

让所有具有nevertype字段的类型都是可选的

Codesandbox: https://codesandbox.io/s/youthful-mclean-csm60i?file=/src/useFetch.ts

解决方案:


import { AxiosError } from 'axios';
import { Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react';
import useSWR, { KeyedMutator } from 'swr';
export { useFetch };
type TUseFetchLoading = {
loading: true;
data?: never;
update?: never;
mutate?: never;
error?: never;
};
type TUseFetchLoaded<T> = {
data: T;
loading?: never;
update: Dispatch<SetStateAction<T>>;
mutate: KeyedMutator<T>;
error?: never;
};
type TUseFetchError = {
error: AxiosError;
loading?: never;
data?: never;
update?: never;
mutate?: never;
};
type TUseFetchReturnType<T> = TUseFetchLoading | TUseFetchLoaded<T> | TUseFetchError;
const useFetch = <T>(url: string | null): TUseFetchReturnType<T> => {
const { data, error, mutate } = useSWR<T, AxiosError>(url ? url : null);
const [fetchedData, setFetchedData] = useState<T>(undefined as unknown as T);
useEffect(() => {
if (data) setFetchedData(data);
}, [data]);
if (!fetchedData && !error) {
return { loading: true };
}
if (error) {
return {
error,
};
}
return {
data: fetchedData,
update: setFetchedData,
mutate,
};
};

相关内容

  • 没有找到相关文章