-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
This is not for TypeScript but for everybody facing type instantiation too deep #34850
Comments
This doesn't always work. But it is one way that can work in some cases. I'm always happy when someone figures out a solution to the max depth/count error for their situation! Down with artificial constraints! To elaborate, there's an upper limit to the number of times you can nest conditional types before getting the max depth error again. So, it is likely that a deeply nested graphql query will still trigger the error. Have you tried nesting your types 100+ layers deep to see if it's okay? I tend to aim for at least 60-80 layers, in general, before being satisfied that a "normal" user of my libraries will never encounter the max depth error |
I had tried with bigger and bigger schemas and... got an error again. Right now the only thing i need to solve is optimising this: export type AliasedReturnType<T> = IsObject<T,{
[P in keyof T]: T[P];
} &
Record<
string,
{
[P in keyof T]: T[P];
}
>,never>; Any ideas? |
Umm.... I don't have any ideas, off the top of my head. When ever I experience the max depth/count issue, I just... Brute force it until I find a way to make it work. See, the problem here is that given a type What we want is to find ways of expressing See,
Also, things work differently between method chaining/function nesting and just having a giant computation. In your case, you're probably using method chaining/function nesting. But I can't give an answer unless I play with the repro for a bit |
More importantly, complex type operators tend to cause the max depth/count error. TS gives us a bunch of primitive type operators,
These type operators take one or more types as input, and can produce a completely new type as an output. We, as library/application developers, use these primitive type operators to form more complex type operators. As you have seen, given a type operator that we want to implement, we can implement it a million other ways. Some of these implementations cause the max depth/count errors. Other implementations sidestep the issue magically. (Generator trampolines, copy-pasting code instead of using recursive types, using conditional types, forcing TS to re-use an existing type, other unintuitive hacks, etc.) At the moment, finding ways around these issues and finding that "perfect" implementation that doesn't cause a max depth/count issue feels a lot like a dark art, rather than a science. |
Found the way to resolve even on very big schemas. I will release new version of Zeus with it this week - stay tuned ! I used Mapped Types combined with inference from Union. |
https://github.com/graphql-editor/graphql-zeus Now with union mapped types! Works with really big schemas without error!!! Tested on 3.7 type GraphQLReturner<T> = T extends Array<infer R> ? SelectionSet<R> : SelectionSet<T>;
type IsUnion<T, YES, NO, U extends T = T> = (T extends any
? (U extends T ? false : true)
: never) extends false
? NO
: YES;
type Anify<T> = { [P in keyof T]?: any };
type MapType<SRC extends Anify<DST>, DST> = DST extends boolean ? SRC : IsUnion<
SRC,
State<SRC>,
DST extends {
__alias: any;
}
? {
[A in keyof DST['__alias']]: Required<SRC> extends Anify<DST['__alias'][A]>
? MapType<Required<SRC>, DST['__alias'][A]>
: never;
} &
{
[Key in keyof Omit<DST, '__alias'>]: DST[Key] extends boolean
? SRC[Key]
: DST[Key] extends [any, infer R]
? ReturnType<Required<SRC>[Key]> extends Array<infer RETURNED> ? MapType<RETURNED, R>[] : MapType<ReturnType<Required<SRC>[Key]> ,R>
: Required<SRC>[Key] extends Array<infer SRCArray>
? MapType<SRCArray, DST[Key]>[]
: MapType<Required<SRC>[Key], DST[Key]>;
}
: {
[Key in keyof DST]: DST[Key] extends boolean
? SRC[Key]
: DST[Key] extends [any, infer R]
? ReturnType<Required<SRC>[Key]> extends Array<infer RETURNED> ? MapType<RETURNED, R>[] : MapType<ReturnType<Required<SRC>[Key]> ,R>
: Required<SRC>[Key] extends Array<infer SRCArray>
? MapType<SRCArray, DST[Key]>[]
: MapType<Required<SRC>[Key], DST[Key]>;
}
>;
type OperationToGraphQL<V, T> = <Z>(o: Z | GraphQLReturner<V>) => Promise<MapType<T, Z>>; So creating union mapped types helped me to work around the error! |
Final form available on my repo |
Hold on everybody facing "Type instantiation is excessively deep and possibly infinite" I think I've just found a solution for
type instantiation too deep error
inhttps://github.com/graphql-editor/graphql-zeus this repo. The solution is to create a conditional type even if you know that the type is the type. I can crawl out the rabbit hole now!
So whats going on here? I had a problem with this error on large schemas, but... not anymore after adding
IsObject
type. The main thing is to drop the type in the type system asnever
even if you know it is a correct type. This is the only way as you tell the compiler that going down is conditional.@orta can you look at it? Correct me if I am wrong but it looks like when the conditional types are closed somehow you can create very generic types.
The text was updated successfully, but these errors were encountered: