Axios is a popular library for performing API calls in JavaScript-based apps, including TypeScript. Luckily Axios provides its own TypeScript typings with the library, meaning you don’t need any extra libraries for it to work with TypeScript.

Today I’ll talk you through using TypeScript with Axios, by providing a type to their generic functions, and how they work together.

I’ll be using the PokeAPI for this article, which is just a free API that provides some pokemon data. You can check it out here.

Why Use Types?

Here’s some straightforward code to fetch the API response for the pokemon Bulbasaur:

async function main() {
    const { data: pokemon } = await axios.get(
        'https://pokeapi.co/api/v2/pokemon/bulbasaur',
        {
            headers: {
                'Accept-Encoding': 'application/json',
            },
        }
    );
    console.log(pokemon);
}

This looks fine, it compiles, and the response executes perfectly fine. So why bother doing anything else?

The benefit here is the same benefit with any other TypeScript program, type safety. At the moment our response has the type any. TypeScript doesn’t know what properties it has, and neither do we. Thankfully the Axios methods are generic, so let’s build some types for our response. The full response is quite large, so I’m going to just implement a subset.

Building Types

Here’s what my response looks like (with some data removed for brevity)

{
  "id": 1,
  "name": "bulbasaur",
  "stats": [
    {
      "base_stat": 45,
      "effort": 0,
      "stat": {
        "name": "hp",
        "url": "https://pokeapi.co/api/v2/stat/1/"
      }
    }
  ],
  "types": [
    {
      "slot": 1,
      "type": {
        "name": "grass",
        "url": "https://pokeapi.co/api/v2/type/12/"
      }
    },
    {
      "slot": 2,
      "type": {
        "name": "poison",
        "url": "https://pokeapi.co/api/v2/type/4/"
      }
    }
  ]
}

Let’s talk through the types I’ve created.

Firstly I’ve created a type union for all our possible stats:

type NormalStats = 'attack' | 'defense';
type PokemonStat = 'hp' | 'speed' | NormalStats | `special-${NormalStats}`;

We can skip writing some of them using some string interpolation.

One pattern that pops up a lot in the response is an object containing the name of a property, and a URL for the API endpoint for more info on it, so we can extract that out into a generic type:

type LinkProperty<T = string> = { name: T; url: string };

And that’s all we need to build the rest of our types:

type BaseStat = {
    base_stat: number;
    effort: number;
    stat: LinkProperty<PokemonStat>;
};

type PokemonType = LinkProperty;

type Pokemon = {
    name: string;
    id: string;
    types: PokemonType[];
    stats: BaseStat[];
};

type PokemonResponse = Pokemon;

Then, we can add our type to our axios.get():

async function main() {
    const { data: pokemon } = await axios.get<PokemonResponse>(

And we get full type inference on our response:

async function main() {
    const { data: pokemon } = await axios.get<PokemonResponse>(
        'https://pokeapi.co/api/v2/pokemon/bulbasaur',
        {
            headers: {
                'Accept-Encoding': 'application/json',
            },
        }
    );

    pokemon.id;
    pokemon.stats[0];
    pokemon.id;
    pokemon.foo; //TS2339: Property 'foo' does not exist on type 'Pokemon'.
}

And that’s all! Our Axios method automatically gives the data object in the response our PokemonResponse type.

This works for any response, as long as you provide a type to the Axios method. If you’re using TypeScript in your apps, I highly recommend this approach, even if you don’t provide as strict a type as I have here.
Thanks for reading, hopefully with this example you’re able to adapt the code for your own scenarios. If you’re using Axios in your React app, we also have an article covering that here. Let me know if you liked this article, or if you’re having any issues!

Avatar photo
👋 Hey, I'm Omari Thompson-Edwards
Hey, I'm Omari! I'm a full-stack developer from the UK. I'm currently looking for graduate and freelance software engineering roles, so if you liked this article, reach out on Twitter at @marile0n

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.