[SOLVED] How to select subtype in typescript (if the field is optional)

Issue

I have following type in Typescript:

export type SomeQuery = {
  __typename?: 'Query'
  viewer?:
    | {
        __typename?: 'Viewer'
        books?:
          | {
              __typename?: 'UserBooks'
              total?: number | undefined | null
              collection: Array<{+
                __typename?: 'UserBook'
                book?:
                   | {
                      __typename?: 'Book'

Since I have the type of the query generated by graphql, I would like to extract the type of a book. I know in TS you can do something like:

type Viewer = SomeQuery['viewer']

This works, the problem is going for the next level, since viewer is optional:

type MyBooks = Viewer['books']

I get as an error:

TS2339: Property 'books' does not exist on type '{ __typename?: "Viewer" | undefined; books?: { __typename?: "UserBooks" | undefined; total?: number | null | undefined; collection: { __typename?: "UserBook" | undefined; book?: { ...;

How can I then get the subtypes if the fields are optional?

PS: according to the answer I manage to get the nested type fields::

type Viewer = NonNullable<MyEventsQuery['viewer']>
type Books = NonNullable<Viewer['books']>
type Collection = NonNullable<Books['collection']>

The problem is now with type Collection, which is an array. I tried:

export type MyBook = Collection['book']
export type MyBook = Collection[number]['book']

The error is:

TS2339: Property 'book' does not exist on type '{ __typename?: "UserBook" | undefined; book?: { __typename?: "Book" | undefined; ... | ... 1 | undefined; } | null | undefined; }[]'.

I think the issue is because of the [] at the end, that indicates that is type array of UserBook, but I don’t know how to get then the type within the array.

Could someone point me to what I should use in the documentation, in order to extract the type in the array?

Solution

You can apply NonNullable utility to Viewer before looking up books.

type MyBooks = NonNullable<Viewer>['books']

Answered By – Long Nguyen Duc

Answer Checked By – Mary Flores (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *