So i have started learning Typescript and im a little stuck when it comes to typing the map function below. When i do nothing i get an error: Property 'id' does not exist on type 'never'. But if i add 'item:any' to the params of the function it fixes it.
But everywhere i read they mention that any should be the last resort. Can someone explain to me how to type this correctly?
Bonus: There is also an error with the section 'error.message' which has the same error which i cant seem to resolve either without adding any.
import React, {useState, useEffect} from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
useEffect(() => {
fetch("https://api.publicapis.org/entries")
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
},
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.map((item) => (
<li key={item.id}>
{item.name} {item.price}
</li>
))}
</ul>
);
}
}
export default App;
CodePudding user response:
You can "easily" fix this by giving TypeScript an hint on what is the type of array of objects you are iterating with map
.
This can be done by using the generic parameter that useState
receives, here is a sample:
interface Item {
id: string;
name: string;
price: number;
}
// Then you need to pass in the type of what you will have in the useState
const [items, setItems] = useState<Array<Item>>([]);
The problem you are facing is due to TypeScript having no clue on what is the type
of the objects that items
may or may not contain. Which will make items
fallback to the type of never[]
, which is just a way of TypeScript warning you that you made something wrong and that you can't use it that way.