Проблемы с правильным определением типа с помощью Typescript и React Query

У меня есть компонент React, который выглядит следующим образом (сильно упрощенный код):

const TestComponent = () => {

    const { data: stuff, isLoading: isLoadingStuff, isSuccess: hasLoadedStuff } = useStuff();

    // ... other similar RQ query wrapper hooks

    const isLoading = isLoadingStuff && isLoadingOtherStuff;
    const loaded = hasLoadedStuff && hasLoadedOtherStuff;

    return (
        <div>
            <Loading isLoading = {isLoading} />
            {loaded && (
                <Stuff stuff = {stuff} />
                <OtherStuff otherStuff = {otherStuff} />    
            )}
        </div>
    )
}

У меня есть несколько запросов RQ, заключенных в специальные перехватчики (например, useStuff). Для повышения читабельности я извлек и переименовал интересующие меня значения с помощью деструктуризации объектов. Однако TS, похоже, не может сделать вывод, что если loading === true, то stuff не может быть undefined, и поэтому я получаю следующую ошибку для stuff = {stuff}:

TS2322: Type string[] | undefined is not assignable to type string[]
Type undefined is not assignable to type string[]

Конечно, если я вернусь к

const stuff = useStuff();
const isLoading = stuff.isLoading && otherStuff.isLoading
// and then
<Stuff stuff = {stuff.data} />

тогда все работает нормально.

Есть ли способ обойти это или мне следует смириться со вторым подходом?

Большое спасибо!

ОБНОВЛЕНИЕ. В идеале я хотел бы иметь возможность возвращать переименованное подмножество параметров RQ из моего пользовательского перехватчика (обычно только данные, isLoading, isSuccess), но я сталкиваюсь с теми же проблемами вывода типа...

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
160
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам просто нужно добавить дискриминируемое объединение в качестве возвращаемого типа ваших перехватчиков. В последних версиях машинописный текст может следовать распознаваемым объединениям посредством как деструктуризации, так и косвенности (если присвоено константным переменным).

type HookResult<T> = 
    | {isLoading: true, data: undefined, isSuccess: undefined}
    | {isLoading: false, isSuccess: false, data: undefined}
    | {isLoading: false, isSuccess: true, data: T } 

function useStuff() : HookResult<Stuff> {
   ///...
}


function useOtherStuff() : HookResult<OtherStuff> {
   ///...
}

const TestComponent = () => {

    const { data: stuff, isLoading: isLoadingStuff, isSuccess: hasLoadedStuff } = useStuff();
    const { data: otherStuff, isLoading: isLoadingOtherStuff, isSuccess: hasLoadedOtherStuff } = useOtherStuff();

    const isLoading = isLoadingStuff && isLoadingOtherStuff;
    const loaded = hasLoadedStuff && hasLoadedOtherStuff;

    return (
        <div>
            <Loading isLoading = {isLoading} />
            {loaded && (<>
                <Stuff stuff = {stuff} />
                <OtherStuff otherStuff = {otherStuff} />    
            </>)}
        </div>
    )
}

Ссылка на игровую площадку

Ответ принят как подходящий

загляните на эту площадку. Я воссоздал ваш пример, и он работает нормально, но вам нужно использовать типы различаемых объединений в реализации вашего перехватчика. может быть, у вас не последняя версия машинописного текста? этот тип отслеживания и вывода был введен не так давно.

Действительно, мне следовало подумать об этом. Обновился до 5.2.4 и теперь работает нормально! Большое спасибо!

ChambreNoire 13.03.2024 19:42

Другие вопросы по теме