Search code examples
javascriptgenericstypescriptaxiosdefinitelytyped

Issue with the DefenitelyTyped of axios


I have installed axios both with npm and typings.

Now, to use it in TypeScript, I need to pass to it a type (T). The problem is that this T is used for both the interface of the request and the interface of the response, which does not make any sense, because obviously the server does not return the same type of data that it receives.

interface ServerRepsonse {
    userID: string;
}

interface ServerRequest {
    username: string;
    password: string;
}

var body = {
        username: "username",
        password: "password"
    };

let response = await axios<ServerRequest>({
            method: 'POST',
            url: "http://localhost:3000/users",
            data: body
        });

alert(response.data.userID);

As you can see, in this example reponse.data.userID would be marked as error. If I passed the ServerResponse interface instead, then "data: body" would be marked as error.

Is that an issue in the index.d.ts file of axios? How can I solve it? I don't want to use "any".


Solution

  • It seems the current implementation does not fully use generics. But you can extend it.

    Install axios types with

    npm i @types/axios
    

    Then create a file typings\axios.d.ts with

    declare namespace Axios {
      interface AxiosInstance {
        <TRequest, TResponse>(config: AxiosXHRConfig<TRequest>): IPromise<AxiosXHR<TResponse>>;
        post<TRequest, TResponse>(url: string, data?: TRequest, config?: AxiosXHRConfigBase<TResponse>): IPromise<AxiosXHR<TResponse>>;
      }
    }
    

    This will allow you to use:

    import * as axios from 'axios';
    
    interface DataToSend {
        name: string;
    }
    interface DataToReceive {
        status: number;
    }
    
    axios<DataToReceive>({ url: '' }).then(r => r.data.status);
    
    axios<DataToSend, DataToReceive>({
        url: '',
        method: 'POST',
        data: { name: '' },
    }).then(r => r.data.status);
    
    axios.post<DataToSend, DataToReceive>('', { name: 'test' })
        .then(r => r.data.status);