Reputation: 525
I'm new in TypeScript and in this simple example I've created a component to fetch data from a fake API and show them in a map
iteration:
import React, { FC, useState } from 'react';
const GetData = (): Promise<[]> => {
return fetch('https://randomuser.me/api/?results=5')
.then((response: any) => response.json())
.then((data: any) => data.results);
}
const App: FC<{}> = () => {
const [users, setUsers] = useState<[]>([]);
const getUsers = (): void => {
GetData().then((data: []) => setUsers(data));
}
return (
<div>
{
<ul>
{
users.map((item: any, index: number) => (
<li key={`user-${index}`}>{`${item.name.first} {item.name.last}`}</li>
))
}
</ul>
}
<button onClick={getUsers}>Load</button>
</div>
)
}
export default App;
This code works well ! but I'm not sure about true of my codes... In this example I've :any
type for functions input (in promise chain eg.) so, is it correct to this example? am I able to use many of any type in arguments when I'll have a nested array in output?
and the second one, I didn't add type with :
for GetData
, but that is a const
and I should declare them something like this:
const age: number = 40;
but I didn't get any error?
Thank you
Upvotes: 2
Views: 278
Reputation: 160
When you are using Promise
generic to define one, you shouldn't add type for callback functions into chain. for example write your chain like this:
const GetData = (): Promise<User[]> => {
return fetch('https://randomuser.me/api/?results=5')
.then((response) => response.json())
.then((data) => data.results);
}
And for second one question about const age: number = 40;
when you define a const
and assign function to that, means you are create a function and TypeScript considers it will be a function and not a primitive value, therefore, you shouldn't add type for const
after that name.
but when you are set something like this: const age: number = 40;
the above code means, your are defining a primitive value and should set type after name.
Upvotes: 1
Reputation: 42160
When you use any
you miss out on most of typescript's error-finding abilities. You are basically saying, "trust me, this is fine" since any
is assignable to any type.
There are a few places that we can improve your types and also a few types that are inaccurate. Promise<[]>
actually means that this is a promise of the empty array []
. You want it to return an array of users: Promise<User[]>
.
You might have this User
object typed somewhere else in your app already. Here I am just defining the properties that we need for this component.
interface User {
name: {
first: string;
last: string;
}
}
Calling fetch
returns Promise<Response>
where Response
is a built-in object type that supports the .json()
method. So instead of (response: any)
you are better off just doing (response)
and using the inferred type. That .json()
method returns Promise<any>
, so the inferred type for data
is any
. You can choose to assert at this point that data
is an object with a property results
containing an array of User
objects, but you can also just stick with the inferred any
and rely on your function's return type to assert that.
const GetData = (): Promise<User[]> => {
return fetch('https://randomuser.me/api/?results=5')
.then((response) => response.json())
.then((data) => data.results);
}
Now to the component. Our state is an array of User
, not an empty array.
const [users, setUsers] = useState<User[]>([]);
Once you change that, you can remove the types from (data: [])
and (item: any, index: number)
. You generally don't need to assert types in a callback when you have proper types higher up in the chain. When you call users.map
, the item
is already known to have type User
because users
is typed as User[]
.
Upvotes: 1
Reputation: 943142
Using any
is a brute force approach that discards all the benefits of using TypeScript on the first place. It works, but isn’t recommended.
Given const age = 40
, TypeScript knows that you are assigning a number. The expression on the right-hand side cannot be anything other than a number. It can infer the type from that so you don’t need to be explicit.
Upvotes: 0