Within our project, we are using the library apollo-angular
. This library comes with predefined generic classes. One of these classes is called Query
and takes two type parameters. These are its default values Query<T = {}, V = EmptyObject>
.
API generator uses these classes to generate an API communication layer, one of these classes looks like this.
class GetPageTypesGQL extends Query<GetPageTypesQuery, GetPageTypesQueryVariables>
export type GetPageTypesQueryVariables = Exact<{ [key: string]: never }>;
export type GetPageTypesQuery = { __typename?: 'Query'; feedPageTypes: Array<string> };
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
In our app we had this type for a very long time, its purpose was simple. You provided a class that implemented the Query
class and returned its first parameter type. And it looked like this.
export type QueryType<T> = T extends Query<infer Q, infer V> ? Q : never;
So for example you could use it like this.
type GetPageType = QueryType<GetPageTypesGQL>
// and the type was GetPageTypesQuery
Unfortunately, this stopped working with the latest Typescript version 4.9.5. Currently, there is some kind of matching which compares Query<T = {}, V = EmptyObject>
with Query<GetPageTypesQuery, GetPageTypesQueryVariables>
and it results in a falsy value so the return type is always never
.
All I came up with until now is
type QueryType<T, Q = any, V = any> = T extends Query<Q, V> ? Q : never;
but it always returns any type or never types, but never extracts the actual type of the first type parameter.
My question to you is, have you experienced something similar or have an idea what might be wrong here? Thank you!