У меня есть компонент 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), но я сталкиваюсь с теми же проблемами вывода типа...





Вам просто нужно добавить дискриминируемое объединение в качестве возвращаемого типа ваших перехватчиков. В последних версиях машинописный текст может следовать распознаваемым объединениям посредством как деструктуризации, так и косвенности (если присвоено константным переменным).
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 и теперь работает нормально! Большое спасибо!