The API request works, great!
But! Are we really sure we are getting back a valid Pokémon?
Even our plain typescript implementation returns unknown
(return type of response.json()
):
const main = async (): Promise<unknown> => {
const response = await fetch("https://pokeapi.co/api/v2/pokemon/garchomp/");
if (!response.ok) {
throw new Error("Response not okay");
}
const json = await response.json();
return json;
};
How do we make sure that we got a Pokémon?
First, let's define a simple interface
for a Pokémon (based on the response from PokéApi):
interface Pokemon {
id: number;
order: number;
name: string;
height: number;
weight: number;
}
Now, we need to type the API response from unknown
to Pokemon
.
This is complex in plain typescript. So much so that most people often default to type casting using as
:
interface Pokemon {
id: number;
order: number;
name: string;
height: number;
weight: number;
}
const main = async (): Promise<Pokemon> => {
const response = await fetch("https://pokeapi.co/api/v2/pokemon/garchomp/");
if (!response.ok) {
throw new Error("Response not okay");
}
const json = await response.json();
return json as Pokemon;
};
as
in typescript is a way to bypass type validation. You are saying: "I know better than you typescript, so listen to me an type this asPokemon
"
as
exposes your codebase to runtime bugs, use it with extreme care (ideally never!)
In reality we are not sure that the response is indeed a valid Pokemon
. We need to introduce runtime validation to check this.
This is where @effect/schema
comes to our rescue!