I'm new to Typescript and trying to add types to a simple app. I'm stuck on an error with a deeply nested object.
export default function AnimalAdoptionCosts() {
const [currencyQuote, setCurrencyQuote] = useState({});
const [userInput, setUserInput] = useState("");
const fetchAdoptionRates = async (userInput: string) => {
const response = await fetch(
`http://localhost:5000/v1/adoptionRate?animal=${userInput}`
);
console.log(response);
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
setCurrencyQuote(body);
};
const handleSubmit = async (userInput: string) => {
await fetchExchangeRates();
const costToAdopt = currencyQuote?.data.quote.USD.price;
};
return (
<>
<form onSubmit={() => handleSubmit(userInput)}>
<label htmlFor="animal">Enter an animal type</label>
<input
value={userInput}
id="userinput"
placeholder="ex: Pomeranian"
onChange={(event) => setUserInput(event.target.value)}
/>
<input type="submit" value="Submit" />
{costToAdopt}
</form>
</>
The Typescript error is: [1] Property 'data' does not exist on type '{}'. TS2339 for this line: const costToAdopt = currencyQuote?.data.quote.USD.price;
I get that this is because useState sets the default as an empty object, but it feels weird to do
interface CurrencyQuote {
data: {
quote: {
USD: {
price: number
}
}
}
is this what I should be doing? I found this example playground to work off of, but then I would make 4 different interfaces, which seems overcomplicated.
Also if you're a TS whiz, I'd love help figuring out how to type out the other important info in my function. Thank you!
If you only need
costToAdopt, I'd recommend just storing that value alone in youruseStateas a number. That makes the typing a lot easier and you can avoid all the nesting.