简体   繁体   中英

Property does not exist on type 'TypedResponse<never>'.ts(2339)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM