Search code examples
typescript

Access deep optional propety of an object with typescript bracket notation


I have a type generated by @graphql-codegen for a query result, and I need to use it as type variable for the ReactTable column utils createColumnHelper.

My query is paginated server-side, and the edges property I want to access in optional in the given query result type.

Typescript is giving me en error: Property 'edges' does not exist on type '{ total?: number | null | undefined; pageInfo: { hasNextPage: boolean; startCursor?: string | null | undefined; endCursor?: string | null | undefined; }; edges?: ({ cursor: string; node?: { ...; } | ... 1 more ... | undefined; } | null)[] | null | undefined; } | null | undefined'.(2339)

I don't understand why does it say it "does not exist" ? Being sure it exists, how can I tell typescript that it exist ?

Here is a short reproduction of the problem :

type SupplierInvoiceListPaginatedQuery = {
    supplierInvoiceListPaginated?: {
        total?: number | null,
        pageInfo: {
            hasNextPage: boolean,
            startCursor?: string | null,
            endCursor?: string | null
        },
        edges?: Array<{
            cursor: string,
            node?: {
                id: string,
                partnerId: string,
                referenceTo: string,
                amount: number,
                datespan?: Array<any> | null,
                docDate?: any | null,
            } | null
        } | null> | null
    } | null
};

let supplierInvoiceList: SupplierInvoiceListPaginatedQuery["supplierInvoiceListPaginated"]["edges"]

=> ["edges"] is underlined with the above described error.

Playground Link

I tried to use the ! non-null assertion operator in different ways combined with bracket notation without success.


Solution

  • SupplierInvoiceListPaginatedQuery["supplierInvoiceListPaginated"] could be undefined or null.

    ["edges"] doesn't exist on undefined or null.

    You could exclude the nullish types and pluck the edges type from the result instead:

    let supplierInvoiceList: Exclude<SupplierInvoiceListPaginatedQuery["supplierInvoiceListPaginated"], undefined | null>["edges"]