Property is missing in type but required in a different type?

Viewed 1157

Still trying to wrap my head around typescript.

I'm trying to type a destructured object like so:

const { authError }: {authError: string} = useRouterQuery()

authError must be a string to work well with other components, but useRouterQuery() is using a different type: ParsedUrlQuery.

So I'm getting the following typescript error: Property 'authError' is missing in type 'ParsedUrlQuery' but required in type '{ authError: string; }'.

Hoping someone can explain the cleanest solution for this.

EDIT: ParsedUrlQuery type returns:

type ParsedUrlQuery = {
    [x: string]: string | string[] | undefined;
}
2 Answers

There is one thing You can do - it is typeguard:

type ParsedUrlQuery = {
    [x: string]: string | string[] | undefined;
}

/**
 * Just a mock
 */
const useRouterQuery = () => ({}) as ParsedUrlQuery

const isAuthorError = (arg: any): arg is { authError: NonNullable<ParsedUrlQuery[string]> } => typeof arg?.authError === 'string'

const result = useRouterQuery()

if (isAuthorError(result)) {
    /**
     * Now you can be sure that authError is either string or string[]
     */
    const { authError } = result
}


const { authError }: ParsedUrlQuery = useRouterQuery()


There is no other way that TS compiler will figure out if authError exists or not.

Here you can find more about typeguards

From the example above, looks like ParsedUrlQuery is an object that has keys of type string ([x: string]) and values which can be string, string[], or undefined.

Like the error mentions, that type doesn't explicitly include an authError key.

What you can do is const { authError }: ParsedUrlQuery = useRouterQuery()

This way, if the object that useRouterQuery returns has an authError key, it'll be destructured and of type string | string[] | undefined.

Related