Как писать типы машинописных текстов для Axios.get при использовании стороннего API

#typescript #axios #next.js

Вопрос:

Первый вопрос, заданный здесь, поэтому я постараюсь подытожить все как можно лучше. Я пытаюсь определить тип данных, которые я получаю от axios.получаю из TMDB-API, который является базой данных фильмов.

Вот как JSON структурирован в моем запросе на получение, который я получаю обратно. (Упрощенно)

 {
    data: {
        results: [
            {
                name: 'Free Guy'
                poster_path: "/yc2IfL701hGkNHRgzmF4C6VKO14.jpg"
            },
            {
                name: 'Squid Game'
                poster_path: "/uu4TgyyW259aOZHN0Ew4TEfjnUG.jpg"
            },
        ]
    }
}
 

Я устанавливаю состояние таким образом

 interface MovieType {
    name: string
    poster_path: string
}

const [movies, setMovies] = useState<MovieType[] | []>([]);
 

Я делаю свой запрос get, который дает мне правильный JSON, указанный выше.
Но я, должно быть, делаю это неправильно, так как ошибка, которую я получаю от машинописного текста, здесь:
Property 'results' does not exist on type 'DataMovieType'.ts(2339)

 interface DataMovieType {
    data: {
        results: MovieType[]
    }
}

const request = await axiosInstance.get<DataMovieType>(fetchUrl);
setMovies(request.data.results);
 

Я могу обойти это, не указывая axios.get<Type>
Но тогда это будет то, чего я не хочу, если только это не единственный способ сделать это.

Я также пытался написать тип DataMovieType подобным образом, но это тоже не работает, так как дает мне ту же ошибку.

 interface DataMovieType {
    data: {
        results: {
            name: string
            poster_path: string
        }
    }
}
 

Я совсем новичок в машинописи, и это может быть простым решением, но сейчас я совершенно потерян, пытаясь решить эту конкретную проблему.

Если потребуется дополнительная информация, я с радостью предоставлю ее вам.

Заранее спасибо, Йохан.

Комментарии:

1. Разве это не должно быть request.data.data.results вместо этого? (хотя я назову request как response )

2. Это избавило меня от ошибки, но она не сработала, установив ее, так как тогда это был пустой объект. Может быть, мой тип данных неверен? Должен ли я удалить данные и записать результаты напрямую? Это действительно сработало, но для меня это не имеет смысла, почему часть данных объекта просто (исчезает)?

3. Да, попробуйте, посмотрев официальную документацию, кажется, что data в JSON нет поля. Тип/интерфейс ( T ), который вы должны предоставить axios.get<T> , отражен в response.data (другими словами, тип response.data T не является типом response ).

4. Огромное спасибо за это, теперь это сработало! Хотя мне это все еще кажется немного странным, так как именно так это выглядит, когда я регистрирую ответ. imgur.com/a/dyQSwMG Но я предполагаю, что это так, как вы описали, по умолчанию это ответ. данные, так как объект конфигурации также из axios. Вот что сбило меня с толку, когда я подумал, что это часть реального объекта. Спасибо!

5. Некоторые профессиональные советы: Просто используйте какой-нибудь инструмент, такой как Postman или Insomnia, чтобы сначала проверить выходные данные API (вы не увидите data / config там, вы увидите, что на самом деле отправил вам сервер). Во-вторых, не утруждайте себя тем, чтобы вручную вводить ответ. Если ответ в формате JSON, то существует множество онлайн-инструментов (например, transform.tools ), которые будут создавать определения типов из ответа для вас. Также смотрите это: github.com/axios/axios/blob/master/index.d.ts#L146 . Он возвращается Promise<R> , и значение по умолчанию R равно AxiosResponse<T> . Так await axios.get<T>() что дам тебе AxiosResponse<T> .

Ответ №1:

Решение от @brc-dd

При просмотре официальной документации выясняется, что в JSON нет поля данных. Тип/интерфейс (T), который вы должны предоставить axios.get, отражается в ответе.данные (другими словами, тип ответа.данные-это не данные ответа).

Что я сделал неправильно, так это включил данные в свой тип, который теперь выглядит так, что сработало для меня.

 interface DataMovieType {
    results: MovieType[]
}