I use GraphQL Code Generator to generate types from my GraphQL queries. One of those types is the following:
type FindAllFilmsQuery = {
__typename?: 'Root';
allFilms?: {
__typename?: 'FilmsConnection';
films?: Array<{
__typename?: 'Film';
id: string;
title?: string | null;
} | null> | null;
} | null;
};
Now I would like to use indexed access types to do the following:
let film: FindAllFilmsQuery['allFilms']['films'][0];
But this yields an error:
TS2339: Property 'films' does not exist on type '{ __typename?: "FilmsConnection" | undefined; films?: ({ __typename?: "Film" | undefined; id: string; title?: string | null | undefined; } | null)[] | null | undefined; } | null | undefined'.
If I set "strict": false
in my TSConfig everything works fine - no error. However, I would like to keep strict
to true
. Is there any solution/recommendation to fix this problem?
Let's look at a much simpler case:
type A = { foo?: { bar: string } }
type B = A['foo']['bar']
// Property 'bar' does not exist on type '{ bar: "baz"; } | undefined'.(2339)
See the problem now?
You can't index optional property like this because you can't index undefined
with anything, and undefined
is a possible value of an optional property.
What you can do is remove all the nullish possible types with NonNullable<T>
.
type A = { foo?: { bar: string } }
type B = NonNullable<A['foo']>['bar'] // fine
However, your example is a few levels deep, so you may need to make things NonNullable
multiple times.
let film: NonNullable<
NonNullable<
FindAllFilmsQuery['allFilms']
>['films']
>[number]