When accessing an index in the form of T[K]
, make sure that K
is indeed a key type for T
; meaning, K extends keyof T
. If T
is a union type, then the definite keys of T
are only those keys present on every member of the union. In this case, keyof (A | B | C)
is represented as
(keyof A) & (keyof B) & (keyof C)
.
In your scenario, since
GetTestimonialsSectionQuery['testimonialsSection']
is a union containing an object type along with both
null
and
undefined
, you cannot access it using any key that is not also part of
null
and
undefined
. As
null
and
undefined
do not have keys to index into, hence the error message:
type Bad = GetTestimonialsSectionQuery[
'testimonialsSection']['testimonials'] // error!
// ----------------------> ~~~~~~~~~~~~~~
// Property 'testimonials' does not exist on type ...
If you are interested in just the object type excluding null
and undefined
, you can use a utility type to filter the union to solely the object type before indexing. Typically, union types can be filtered using the Exclude<T, U>
utility type, but specifically for removing null
and undefined
, you can utilize the NonNullable<T>
utility type:
type Testimonials = NonNullable<
GetTestimonialsSectionQuery['testimonialsSection']
>['testimonials']
/* type Testimonials = {
__typename?: "Testimonial" | undefined;
id: string;
text: string;
author?: {
__typename?: "TestimonialAuthor" | undefined;
id: string;
name: string;
photo: {
__typename?: 'Asset';
url: string;
};
} | null | undefined;
}[] */
type Testimonials = NonNullable<
GetTestimonialsSectionQuery['testimonialsSection']
>['testimonials']
/* type Testimonials = {
__typename?: "Testimonial" | undefined;
id: string;
text: string;
author?: {
__typename?: "TestimonialAuthor" | undefined;
id: string;
name: string;
photo: {
__typename?: 'Asset';
url: string;
};
} | null | undefined;
}[] */
Great job!
Playground link to code