I have a server side data loader that retrieves a user's ID from a data model, then checks that the user ID actually exists here:
export const loader = async ({ request, params }: LoaderArgs) => {
const REQUESTED_USER = await GetUserById(Number(params.id))
if (!REQUESTED_USER) {
/**
* If the provided url params user ID does not exist, we will handle it here
*/
return redirectWithError({
request,
message: `User ID: ${params.id} was not found; please enter a valid User ID`,
logMessage: `User ID: ${params.id} was not found; please enter a valid User ID`,
redirectTo: '/manager'
})
}
}
REQUESTED_USER returns:
const REQUESTED_USER: {
id: number;
company_name: string | null;
avatar: string | null;
brand: string | null;
email: string;
name: string | null;
favicon: string | null;
} | null
There is code after that block that does some data manipulation, then returns the data in a typed JSON response:
if (GET_SELECTED_SERVICES) {
sma = unwrap_sma[0]
edr = unwrap_edr[0]
cma = unwrap_cma[0]
vms = unwrap_vms[0]
}
return typedjson({
sma,
vms,
cma,
edr,
user
})
After which I am passing it to a component in React on the client side:
export const ReadUser = ({ }) => {
const LOADER = useTypedLoaderData<typeof loader>();
const [CSRF] = useCSRF()
return (
<main className="flex w-full">
<Form method="post" className="flex w-full">
<input className="hidden" name={'csrf'} value={CSRF} type="text" readOnly />
<Profile SMA={LOADER.sma} EDR={[]} VMS={[]} CMA={[]} />
</Form>
</main>
)
}
However, the attributes on the Profile
component are throwing this error:
Property 'sma' does not exist on type 'TypedResponse<never> | TypedJsonResponse<{ sma: TOptions[]; vms: TOptions[]; cma: TOptions[]; edr: TOptions[]; user: { id: number; company_name: string | null; ... 4 more ...; favicon: string | null; }; }>'.
Property 'sma' does not exist on type 'TypedResponse<never>'.ts(2339)
I have determined it is because of the initial REQUESTED_USER
guard in the server-side loader
function, whereby the LOADER
response is never fulfilled. I assume? this is due to Typescript not understanding the fulfillment of the request, but not 100% on that (if someone could elucidate on that).
Otherwise, how do I go about fixing this?
The type of the LOADER
const in ReadUser
component is:
const LOADER: TypedResponse<never> | TypedJsonResponse<{
sma: TOptions[];
vms: TOptions[];
cma: TOptions[];
edr: TOptions[];
user: {
id: number;
company_name: string | null;
... 4 more ...;
favicon: string | null;
};
}>
I did try to change the !REQUESTED_USER
argument to REQUESTED_USER === null
and that did not change anything
I assume your loader can return types A = {x:1}
and B = {y:2}
, that results in union A | B
A | B
type for typeof loader
. If you try to access LOADER.x
ts will complain because LOADER
can be of type B
and there is no property x
on it, same the other way around.
As types are inferred correctly by what you actually return and there is no pretty way to discriminate union for or case , you can only assign type manually useTypedLoaderData() as A
or throw redirect that will remove first return type from union and seems also work in remix - throw redirect('/somewhere')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.