I am trying to create a function overload for an API call with a delete
method. Here's what I have so far:
type ApiCore = { endpoint: string; key: string };
export type ApiParams = {
routeParam?: string;
queryParams?: FormatQueryParams;
};
function deleteApi(
core: ApiCore
): (ids: string[], params?: ApiParams) => Promise<string[]>;
function deleteApi<Schema>(
core: ApiCore
): (params: ApiParams, param2?: ApiParams) => Promise<Schema & BaseSchema>;
function deleteApi<Schema>({
endpoint,
key,
}: ApiCore): (
param1: string[] | ApiParams,
param2?: ApiParams
) => Promise<(Schema & BaseSchema) | string[]> {
return async function (param1, param2 = {}) {
if (Array.isArray(param1)) {
const { queryParams, routeParam } = param2;
const { data } = await api.delete(
`${endpoint}${routeParam ? `/${routeParam}` : ''}${formatQueryParams(
queryParams
)}`,
{ data: { [key]: param1 } }
);
return data.result || data.data;
}
const { queryParams, routeParam } = param1;
const { data } = await api.delete(
`${endpoint}${routeParam ? `/${routeParam}` : ''}${formatQueryParams(
queryParams
)}`
);
return data.result || data.data;
};
}
The function is being curried because it will be passed to a factory function that creates other requests. As you can see, the inner asynchronous function requires at least one argument, which can either be string[]
or ApiParams
object. The problem is that whenever I would pass in an array of strings, Typescript complains that Type 'string[]' has no properties in common with type 'ApiParams'
such as in this implementation:
const service = (endpoint: string, key: string) => ({
delete: (param1: string[] | ApiParams, param2?: ApiParams) =>
deleteApi({ endpoint, key })(param1, param2)
// ^Type 'string[]' has no properties in common with type 'ApiParams'
})
I'm confused, shouldn't it accept it? Thank you.
I guess you are overcomplicating, just return an overloaded function and use it directly:
type ApiCore = { endpoint: string; key: string };
type FormatQueryParams = {};
type BaseSchema = {};
export type ApiParams = {
routeParam?: string;
queryParams?: FormatQueryParams;
};
function deleteApi({ endpoint, key,}: ApiCore)
{
function out(ids: string[], params?: ApiParams): Promise<string[]>;
function out(params: ApiParams, params2?: ApiParams): Promise<BaseSchema>
async function out(param1: string[] | ApiParams, param2: ApiParams = {}){
return 1 as any;
}
return out;
}
const service = (endpoint: string, key: string) => ({
delete: deleteApi({ endpoint, key })
});
const s = service('','');
s.delete([]).then(r =>{
r; // string[]
});