It is not bad practice to write down the type explicitly when the type is any
. Quite the contrary, it is a great practice to define explicit types when a cannot infer the type - as in this case.
You won’t be error-free, since eventually you can assign a "wrong" type, but that’s not always the case.
In this case - an HTTP request -, unless you are using an type Guard (that would bring as much type security as possible), note down a type to any
is a valid option too.
The problem is that the type you are noting as function return is:
{
userId: number;
id: number;
title: string;
body: string;
}[];
And this type is different (and not attributable) to the type Promise<any>
, because that guy is not a Promise
.
It is also worth mentioning that all asynchronous function (annotated with async
) return a promise, which also invalidates the explicit annotation.
To correct, while still keeping the explicit return, you must clarify that the function is returning a Promise
something. Therefore, the return annotation should be something like:
Promise<{
userId: number;
id: number;
title: string;
body: string;
}[]>;
Promise<T>
is a generic type embedded in the Typescript library. You can consult here.
This means a promise that will resolve in an object array (with the specified signature).
Then your function will look something like:
const getPeople: () => Promise<{
userId: number;
id: number;
title: string;
body: string;
}[]> = async () => {
const url = 'https://jsonplaceholder.typicode.com/posts?_limit=2';
const response: Response = await fetch(url);
const data = await response.json();
return data;
};
However, I don’t recommend using the annotation that way, since you’re giving a type to a Arrow Function, and not necessarily on his return. Personally, I would do so:
interface Post {
userId: number;
id: number;
title: string;
body: string;
}
// Estamos anotando o tipo explicitamente no retorno da função:
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
async function getPeople(): Promise<Post[]> {
const url = 'https://jsonplaceholder.typicode.com/posts?_limit=2';
const response: Response = await fetch(url);
const data = await response.json();
return data;
}
See on Typescript playground.
Another option is to annotate the type directly in the variable and let Typescript infer the return of the function:
interface Post {
userId: number;
id: number;
title: string;
body: string;
}
async function getPeople() {
const url = 'https://jsonplaceholder.typicode.com/posts?_limit=2';
const response: Response = await fetch(url);
// Estamos anotando o tipo explicitamente na variável:
// ↓↓↓↓↓↓
const data: Post[] = await response.json();
return data;
}
See on Typescript playground.
Thank you so much for your help!
– Thales Maia