const[recipes, setRecipes] = React.useState<Irecipe>();
async function fetchApi(){
try{
const response = await axios.get<Irecipe>(`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`);
setRecipes(response.data);
console.log(recipes)
}catch(e: unknown){
console.warn(e);
}
}
React.useEffect(()=> {
fetchApi()
}, [query]);
export interface IfetchApi{
config?: any,
headers?:any,
data: Idata[],
request?: number,
statusText?: string
}
export interface Idata {
count: number,
from: number,
hits: Irecipe,
more: boolean,
q: string,
}
export interface Irecipe{
calories: number,
cautions: any,
cuisineType: Array,
dietLabels: Array,
dishType: any,
healthLabels?: any,
image: string,
ingredientLines: Array,
ingredients: Iingredients[],
label: string,
mealType: Array,
shareAs: string,
source: string,
totalDaily: any,
totalNutrients: any,
totalTime: number,
totalWeight: number,
uri: string,
url: string,
yield: number
}
export interface Iingredients{
text: string,
quantity: number,
measure: string
}




json, лучше тыкнуть в консоли на ответе "Copy object" и вставь в любой конвертер, который гуглится по "json to ts", например https://app.quicktype.io/. Так ты точно не ошибёшься, а потом уже можешь уточнить тип руками. unknown и прогонять через тайпгард, проверяя руками, что он соответствует типу, но это не частая практика, увы.
const[recipes, setRecipes] = React.useState<Welcome>();
async function fetchApi(){
try{
const response = await axios.get<Welcome>(`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`);
setRecipes(response.data);
console.log(recipes?.hits[0].recipe.calories) //Тут данные с обьекта выводятся
}catch(e: unknown){
console.warn(e);
}
}
React.useEffect(()=> {
fetchApi()
}, [query]);
const gainSearch = (event: React.FormEvent) => {
event.preventDefault();
setQuery(search);
setSearch('');
}
const updateSearch = (event: any)=>{
setSearch(event.target.value);
}
return (
<div className="App">
{recipes.map((recipe:Welcome) => {
<Recipe key={recipe.hits}/> //Здесь уже получаю ошибку <blockquote>Object is possibly 'undefined'.</blockquote>
})}
</div>
);
}
export default App;
setRecipes всё ещё кладёшь response.data, в response.data у тебя весь ответ от сервера. Это не массив, а объект, вот этот: 
map'ом пройтись по объекту.recipes - может быть undefined, потому что тут const[recipes, setRecipes] = React.useState<Welcome>(); не задал значение по умолчанию: useState() условно то же самое, что useState(undefined), а значит у тебя в recipes лежит undefined до тех пока не придёт ответ от сервера. А ответ от сервера может прийти через сто лет, к тому времени компонент уже нарисовался и recipes.map был вызван, т.е. undefined.map, а это ошибка и падение скрипта. TS не даёт тебе этого сделать. Ты должен либо добавить проверку, что recipes существует, либо задать значение по умолчанию, например пустой массив.const[recipes, setRecipes] = React.useState<Welcome>([]);Argument of type 'never[]' is not assignable to parameter of type 'Welcome | (() => Welcome)'
const[recipes, setRecipes] = React.useState<Welcome[]>([]);
async function fetchApi(){
try{
const response = await axios.get<Welcome[]>(`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`);
setRecipes(response.data);
console.log(recipes)
}catch(e: unknown){
console.warn(e);
}
}const[recipes, setRecipes] = React.useState<Irecipe[]>([]);
async function fetchApi(){
try{
const response = await axios.get<Irecipe[]>(`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`);
setRecipes(response.data);
console.log(recipes)
}catch(e: unknown){
console.warn(e);
}
}setRecipes(response.hits); setRecipes(response.data);
React.responce.data у тебя корневой объект ответа, а не массив. Не массив. Не. Массив. setRecipes массив hits, то и клади туда, блин, массив hits: setRecipes(response.data.hits).setRecipes не меняет магически на лету recipes, он обновляет state(состояние) компонента. Поэтому функция и называется useState, а не как-то ещё.recipes будет тем которое ты установил.recipes пустым массивом, создаётся функция fetchApi в которую замыкается пустой recipes.useEffect и вызывает функцию fetchApi.setRecipes, выводится console.log с запомненным пустым recipes.setRecipes инициирует повторную отрисовка компонента(повторный вызов функции-компонента), при которой в recipes уже лежит то, что туда положили на предыдущем шаге. После отрисовки useEffect не срабатывает, т.к. query не менялся.
Если ты хочешь положить в setRecipes массив hits, то и клади туда, блин, массив hits: setRecipes(response.data.hits).
setRecipes(response.data.hits). то сразу же получаю ошибку Property 'hits' does not exist on type 'Ingredient[]', подставлял абсолютно все интерфейсы и везде одни и та же ошибка.
Property 'hits' does not exist on type 'Ingredient[]' только если ты сам напишешь вот так await axios.get<Ingredient[]>.... Т.е. ты прямым текстом говоришь typescript'у, что в ответе сервера ждёшь МАССИВ Ingredient[], а не объект, имеющий поле hits, а потом удивляешься, что он тебе об этом прямо говорит.const [recipes, setRecipes] = React.useState<Welcome["hits"]>([]);
const fetchApi = () => {
try {
fetch(
`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`
)
.then((res) => res.json())
.then((data) => setRecipes(data.hits));
} catch (e) {
console.log(e);
}
};
console.log(recipes);hitsкоторый состоит из нескольких обьектов но я не могу по-нему пробежаться мапом..
const [recipes, setRecipes] = React.useState<Welcome["hits"]>([]);
async function fetchApi() {
try {
const response = await axios.get<Welcome["hits"]>(
`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`
);
setRecipes(response.data); //hits не дает записать, <blockquote>Property 'hits' does not exist on type 'Hit[]'</blockquote>
console.log(recipes);
} catch (e: unknown) {
console.warn(e);
}
}только если ты сам напишешь вот так await axios.get.... Т.е. ты прямым текстом говоришь typescript'у, что в ответе сервера ждёшь МАССИВ Ingredient[], а не объект, имеющий поле hits, а потом удивляешься, что он тебе об этом прямо говорит.- выходит что моя новая запись
const [recipes, setRecipes] = React.useState<Welcome["hits"]>([]);
const response = await axios.get<Welcome["hits"]>(
`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`
); тоже неверная тк как я тут тоже ожидаю массив а должен ожидать обьект. Смотрел документацию и некоторые туториалы и там получение данных происходит примерно так же как я и написал. Может дело в типах ?
axios(сервер) тебе вернёт Welcome, а не Welcome['hits'], потому так и пиши: const response = await axios.get<Welcome>(
`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`
); А вот в setRecipes ты уже хочешь положить именно Welcome['hits'] а не весь Welcome, потому тоже так и пиши React.useState<Welcome["hits"]>([])
// ...
setRecipes(response.data.hits)axios просто устанавливает какой тип будет у response.data. function App() {
const [search, setSearch] = React.useState("");
const [query, setQuery] = React.useState<string>("steak");
const [recipes, setRecipes] = React.useState<Welcome["hits"]>([]);
async function fetchApi() {
try {
const response = await axios.get<Welcome>(
`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`
);
setRecipes(response.data.hits);
} catch (e: unknown) {
console.warn(e);
}
}
console.log(recipes);
React.useEffect(() => {
fetchApi();
}, [query]);
const gainSearch = (event: React.FormEvent) => {
event.preventDefault();
setQuery(search);
setSearch("");
};
const updateSearch = (event: any) => {
setSearch(event.target.value);
};
return (
<div className="App">
{recipes.map((recipe) => (
<Recipe
key={recipe.recipe.label}
title={recipe.recipe.label}
image={recipe.recipe.image}
calories={recipe.recipe.calories}
ingredients={recipe.recipe.ingredients}
/>
))}
</div>
);
}
(property) title: any
Type '{ key: any; title: any; image: any; calories: any; ingredients: any; }' is not assignable to type 'IntrinsicAttributes'.
Property 'title' does not exist on type 'IntrinsicAttributes'.

export interface Hit {
recipe: Recipe[];
} -> export interface Hit {
recipe: Recipe;
}Recipe и компонент Recipe, они конфликтуют скорее всего. Также возможно сам компонент Recipe не типизирован, т.е. ts не знает какие пропсы он принимает, а какие нет.<список переданных пропсов> нельзя назначить в <стандартные атрибуты для React-комонента>, пропс title отсутствует в <стандартные атрибуты для React-комонента>". function App() {
const [search, setSearch] = React.useState("");
const [query, setQuery] = React.useState<string>("steak");
const [recipes, setRecipes] = React.useState<Welcome["hits"]>([]);
async function fetchApi() {
try {
const response = await axios.get<Welcome>(
`https://api.edamam.com/search?q=${query}&app_id=${ID}&app_key=${KEY}`
);
setRecipes(response.data.hits);
} catch (e: unknown) {
console.warn(e);
}
}
console.log(recipes);
React.useEffect(() => {
fetchApi();
}, [query]);
const gainSearch = (event: React.FormEvent) => {
event.preventDefault();
setQuery(search);
setSearch("");
};
const updateSearch = (event: any) => {
setSearch(event.target.value);
};
return (
<div className="App">
{recipes.map((recipe) => {
<h2>{recipe.recipe.calories}</h2>; //не отображается
})}
</div>
);
}
export default App;
const recipes: Hit[]
Type 'void[]' is not assignable to type 'ReactNode'.
Type 'void[]' is not assignable to type 'ReactFragment'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
Type 'IteratorResult' is not assignable to type 'IteratorResult'.
Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'.
Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'.
Type 'void' is not assignable to type 'ReactNode'.
<div className="App">
{recipes.map((recipe): any => {
<h2>{recipe.recipe.calories}</h2>;
})}
</div><div className="App">
{recipes.map((recipe) => {
<Recipe
key={recipe.recipe.label}
image={recipe.recipe.image}
calories={recipe.recipe.calories}
ingredients={recipe.recipe.ingredients}
/>;
})}
</div>import React from "react";
interface IProps {
label: string;
image: string;
calories: number;
ingredients: Array<any>;
}
export default function Recipe({
label,
image,
calories,
ingredients,
}: IProps) {
return <h1>{calories}</h1>;
}
return - она ничего и не возвращает. React в этом плане ничего не меняет.recipes.map((recipe) => {
<h2>{recipe.recipe.calories}</h2>; //не отображается
}) ->recipes.map((recipe) => {
return (<h2>{recipe.recipe.calories}</h2>);
}) или recipes.map((recipe) => (
<h2>{recipe.recipe.calories}</h2>;
))