Skip to content
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

Large enum causes React hook deps error TS2590 Expression produces a union type that is too complex to represent #41615

Closed
brieb opened this issue Nov 20, 2020 · 2 comments · Fixed by #42353
Assignees
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@brieb
Copy link

brieb commented Nov 20, 2020

We use React hooks with TypeScript and ran into an issue where we were passing a large enum into the dependency array of the hook function, resulting in TS2590 Expression produces a union type that is too complex to represent

This is an example type signature of a hook
function React.useEffect(effect: React.EffectCallback, deps?: React.DependencyList | undefined): void

Even though the deps type is React.DependencyList which is type DependencyList = ReadonlyArray<any>; it appears to be attempting a union deps: (MyEnum1 | MyEnum2 | MyInterface)[] even though the type is ultimately discarded.

This gives the same error const deps: any[] = [MyEnum1.Key0, MyEnum2.Key0, obj];

We could do [MyEnum1.Key0 as any, MyEnum2.Key0 as any, obj] but that is not ideal and also breaks the rules of hooks eslint rule.

Another workaround we came up with was [MyEnum1.Key0, MyEnum2.Key0, obj] as const to avoid the unioning (though this fails the hooks eslint rule which sounds like a separate issue).

Thanks in advance for your help.

TypeScript Version: 4.0.5

Search Terms: react hooks deps, dependency array, union type that is too complex

Code

https://gist.github.com/brieb/ef53a9e48e8a5dec6cfa7d2cfda22623

Expected behavior:

No compiler error

Actual behavior:

TS2590 error: Expression produces a union type that is too complex to represent.

Playground Link:

Link

Related Issues:
#33130

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Dec 1, 2020
@DanielRosenwasser
Copy link
Member

This gives the same error const deps: any[] = [MyEnum1.Key0, MyEnum2.Key0, obj];

It really sounds like the hooks thing is a separate issue and it comes down to 2 large enums and an object type...

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Dec 3, 2020

So one thing that I know will help is combining your enums into one.

Otherwise, we don't currently have a good heuristic to avoid triggering the subtype reduction check. I did try the following really naive change to avoid flattening out the entire enum:

         function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) {
             const flags = type.flags;
-            if (flags & TypeFlags.Union) {
+            if (flags & TypeFlags.Union && !(flags & TypeFlags.EnumLike)) {
                 return addTypesToUnion(typeSet, includes, (<UnionType>type).types);

but for some reason I had issues running locally in parallel.

Maybe @ahejlsberg or @weswigham have some ideas here.

@DanielRosenwasser DanielRosenwasser added In Discussion Not yet reached consensus Suggestion An idea for TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels Jan 11, 2021
@ahejlsberg ahejlsberg self-assigned this Jan 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants