Я новичок в Typescript и пытаюсь добавить типы в простое приложение. Я застрял на ошибке с глубоко вложенным объектом.
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.info(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>
</>
Ошибка Typescript: [1] Property 'data' does not exist on type '{}'. TS2339
для этой строки: const costToAdopt = currencyQuote?.data.quote.USD.price;
Я понимаю, что это потому, что useState устанавливает значение по умолчанию как пустой объект, но это странно.
interface CurrencyQuote {
data: {
quote: {
USD: {
price: number
}
}
}
это то, что я должен делать? Я нашел эту примерную игровую площадку для работы, но тогда я бы сделал 4 разных интерфейса, что кажется слишком сложным.
Кроме того, если вы гений TS, я бы хотел помочь выяснить, как вводить другую важную информацию в моей функции. Спасибо!
@Ник, хорошая мысль, я понял, упрощая свой код, я испортил имена некоторых переменных, теперь это currencyQuote
, и после установки costToAdopt я хочу отобразить результат
Даже с учетом этого изменения переменной, я думаю, вы правы в том, что ей не нужно сохранять состояние, я, вероятно, могу просто вернуть costToAdopt
в fetchAdoptionRates fn
При всем при этом я по-прежнему считаю, что в целом стоит написать полную типизацию для возвращаемого типа данных. Это дает вам все преимущества TS!
Если вам нужно только costToAdopt
, я бы рекомендовал просто сохранить это значение отдельно в вашем useState
в виде числа. Это значительно упрощает набор текста, и вы можете избежать вложения.
const [costToAdopt, setCostToAdopt] = useState<number>(0);
// ...
const fetchAdoptionRates = async (userInput: string) => {
const response = await fetch(
`http://localhost:5000/v1/adoptionRate?animal=${userInput}`
);
console.info(response);
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
setCostToAdopt(body?.data?.quote?.USD?.price || 0);
};
// ...
Спасибо! Это очень помогло и упростило некоторые вещи. Я пошел дальше и добавил подобные типизации ко всем моим функциям useState. const [cryptos, setCryptos] = useState<Object>({}); const [conversionRateToUSD, setConversionRateToUSD] = useState<число>(0); const [userInput, setUserInput] = useState<string>(""); Есть ли что-то еще, что я должен сделать с точки зрения интерфейсов?
Вместо ввода Object
вместо cryptos
я бы создал интерфейс с ключами, которые вы будете использовать в криптографии, и использовал бы его, чтобы вы могли получить доступ к свойствам без ошибок типа.
Первое, что я замечаю, это то, что нет причин для
adoptionRates
сохранять состояние, если только вы не используете его где-то еще?