goju
goju

Reputation: 25

Typescript: Return function Type Guarding using Generics problems

so im pursuing to have generic function to call axios in my react project. since i need it to be as generic so i can using it with my condition on my repo, so i came up with an idea like this

type XHR = 'get' | 'post' | 'delete'
function callApi(url: string) {
/\*\* will do some logic here \*/

    return <Response = any, Methods = XHR>(
        methodName: Methods,
        spec?: Methods extends 'get' ? never : object,
    ): Promise<Response> => {
        switch (methodName) {
            case 'get':
                return axios.get<Response>(url).then((resp) => resp.data)
            case 'delete':
                return axios
                    .delete<Response>(url, { data: { data: spec } })
                    .then((resp) => resp.data as Response)
            default:
                return axios[methodName as Exclude<XHR, 'delete' | 'get'>]<Response>(
                    url,
                    {
                        data: spec,
                    },
                ).then((resp) => resp.data)
        }
    }

}

so i can call the function in my hooks like

let callGoogle = callApi('https://google.com')

return callGoogle('get')

//or
return callGoogle('post', {spec: 'foo'})

but here's the problem, there must be something wrong when i declaring the return function on callApi that make this not returning error

// need to throw ts error, since post need two paramaters
let result2 = callGoogle<{ rambo: number }>('post')

if my question still unclear, please let me know what's i missing in this.

already tried some of the code above, and also already giving ts playground to test it out with some cases there

here's typescript playground to test it out

TypeScript Playground

already tried in vs code and typescript playground like above

Upvotes: 0

Views: 42

Answers (1)

Tanek Loc
Tanek Loc

Reputation: 361

Try to define your arguments as an array and then decide how many are required:

...args: U extends 'get' ? [] : [object]

Playground link.

Upvotes: 1

Related Questions