My goal is to develop a utility function that enhances the fetch functionality within our application. One of the key aspects I want to incorporate is the ability to accept an optional Transform Function option for altering the data format returned.
type TransformFn<TResponse, TData> = (arg0: TResponse) => TData;
interface AppFetchInit extends RequestInit {
errMsg?: string;
transformFn?: undefined;
}
interface AppFetchInitWithTransformFn<TResponse, TData> extends Omit<AppFetchInit, 'transformFn'> {
transformFn: TransformFn<TResponse, TData>;
}
interface AppFetchOverload<TResponse, TData = TResponse> {
(apiURI: string, init: AppFetchInit): TResponse;
(apiURI: string, init: AppFetchInitWithTransformFn<TResponse, TData>): TData;
}
export const appFetch: AppFetchOverload<TResponse, TData> = async (
apiURI,
{ errMsg, transformFn, ...init } = {}
) => {
const response = await fetch(apiURI, init);
if (!response.ok)
throw new Error(errMsg ?? `Fetching ${apiURI} failed: ${response.statusText}`);
const responseJson = (await response.json()) as TResponse;
return transformFn ? transformFn(responseJson) : responseJson;
};
While I anticipate this solution to be effective, I encounter errors related to the implementation signature, such as Cannot find name 'TResponse'
and Cannot find name 'TData'
. Despite being in a .ts file, which should not interpret <TResponse, TData>
as jsx, these issues persist. What could be causing these errors?
Moreover, I am unsure about the correctness of the AppFetchInit
and AppFetchInitWithTransformFn
interfaces. For instance, does having transformFn
as an optional property in AppFetchInit
impact the ability to destructure it in the implementation signature? Could providing a transform function in a call potentially lead to incorrectly typing the return value?