-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
“Type instantiation is excessively deep and possibly infinite” but only in a large codebase #34933
Comments
That's a lot of properties ._. |
@AnyhowStep That's correct. The component in question mixes-in the props defined by |
We have the same issue in one of our larger projects. Works fine with 3.6.4 but not with 3.7.2 Using type |
Same issue, using |
in
So the value is hard-coded. Perhaps a configuration option to change this might be warranted. As a workaround for now, you could try upping this limit and rebuilding the compiler. |
There have been proposals made to increase the limit. They've been rejected because it's seen as an "implementation detail" that should not be exposed. PR: #29602 Comment by @ahejlsberg
I agree with this part,
If you're writing library code, you should not be messing with this limit. If you're writing application code and can force everyone on your team to use a hacked version of TS... You can go ahead and hack the .js files for tsc and tsserver. Then, use https://www.npmjs.com/package/patch-package and commit the patch files |
@Stianhn @rista404 Have you managed to reproduce this issue using a more reduced example? If what we're dealing with is a valid use case, then understanding it could help us come up with a heuristic for when type instantiation limit should not be applied. I agree that messing with the internals leads nowhere — after all, you need to draw the boundary somewhere. As far as I know, this limit is not something new. It existed before, yet somehow this code stopped working. I wonder what changed that directly influenced our use cases. |
git bisect? =x |
Can you grant @weswigham permission to the repository as well? |
@DanielRosenwasser Yes! Invite sent @weswigham. |
Another example in https://github.com/elastic/kibana/pull/47188/checks?check_run_id=303150613 where @timroes is trying to upgrade TS to 3.7.2:
Related pull request: Related file: edit: this issue will be fixed with the aforementioned pull request. We've added an explicit intermediary type (elastic/kibana@ef912fc) that resolves the issue for 3.7. |
Worth noting that if you're upgrading from TS 3.5, something about how I'm bringing this up because it looks like @dgieselaar is migrating from TS 3.5 I also have a todo on my personal project to investigate this, AnyhowStep/tsql#25 But I'm not focusing on TS 3.7 support yet |
We have a similar issue with this code (roughly):
|
I have a similar issue with grommet-icons v4.4.0: If I use the trash icon directly, all fine. If I wrap it with styled from styled component, I get the same message. No problem until typescript 3.5.2. No Problem:
Problem with 3.7.2:
|
Same issue with styled components extending rmwc components: import * as React from 'react'
import styled from 'styled-components'
import { Button } from '@rmwc/button'
const ButtonStyled = styled(Button)`
`
export function ConnectionSetting() {
return <React.Fragment>
<ButtonS />
</React.Fragment>
} |
So what is the fix here. Nothing yet ? and we should not update to latest ts ? or refactor application code within limits ? |
Hitting this issue. Using zod to merge several sub-schemas into a "complete" schema, resulting in the error. Hard-coding the resultant large schema works fine, but is more of a pain to maintain/less re-usable |
Was also experimenting with Zod schemas. In my case, this would negate all my efforts to validate the API using Zod. Here is a sandbox, where I try to make a Zod union of basic object keys. In addition to showing the error message, an unexpected value of |
I had similar issue with zod, instead using z.merge or z.extend I used spread operators export const addNewProspectSchema = z.object({
...generalSchema.shape,
...landSchema.shape,
...pvResourceSchema.shape,
...windResourceSchema.shape,
...productionSchema.shape,
...gridSchema.shape,
...
});
type AddNewProspectSchema = z.infer<typeof addNewProspectSchema>; This solved the issue, at least for now. :) |
In case it helps someone, I think I was triggering this error attempting to combine some const elems: Promise<JSX.Element>[] = []
const nodes: Promise<ReactNode>[] = []
const all = Promise.all([ ...elems, ...nodes ]) This fails to compile:
In my case, both arrays could be refined to |
Very nice!! I have a similar problem. I was using merge, pick and extend. After seeing your comment, I simplified the schema using the spread. Any ideas on how to resolve it? const getMonthlyInsuredItemSchema = monthlyInsuredItemSchema.pick({
month: true,
processedAt: true,
});
const getInsuredItemSchema = insuredItemSchema.pick({
externalId: true,
additionalAttributes: true,
remainingInstallments: true,
totalInstallments: true,
installmentAmount: true,
});
const getInsuredPersonSchema = insuredPersonSchema.pick({
name: true,
cpf: true,
birthdate: true,
gender: true,
});
const getInsuredItemsResponse = z.array(
z.object({
...getMonthlyInsuredItemSchema.shape,
...getInsuredItemSchema.shape,
insuredPerson: getInsuredPersonSchema,
}),
); UpdateThe problem was in I believe that what causes the error is the fact that the field is a jsonb in the database, receives a type transformation from drizzle-zod, and is then extended in another schema, generating many recurring type instantiations. What I did was remove the additionalAttributes from the pick and redefine it explicitly in the |
…improve validation error messages (#171452) **Epics:** elastic/security-team#8058, elastic/security-team#6726 (internal) **Partially addresses:** elastic/security-team#7991 (internal) ## Summary The main benefit of this PR is shown in `rule_request_schema.test.ts`, where the error messages are now more accurate and concise. With regular unions, `zod` has to try validating the input against all schemas in the union and reports the errors from every schema in the union. Switching to discriminated unions, with `type` as the discriminator, allows `zod` to pick the right rule type schema from the union and only validate against that rule type. This means the error message reports that either the discriminator is invalid, in any case where `type` is not valid, or if `type` is valid but another field is wrong for that type of rule then the error message is the validation result from only that rule type. To make it possible to use discriminated unions, we need to switch from using zod's `.and()` for intersections to `.merge()` because `.and()` returns an intersection type that is incompatible with discriminated unions in zod. Similarly, we need to remove the usage of `.transform()` because it returns a ZodEffect that is incompatible with `.merge()`. Instead of using `.transform()` to turn properties from optional to possibly undefined, we can use `requiredOptional` explicitly in specific places to convert the types. Similarly, the `RequiredOptional` type can be used on the return type of conversion functions between API and internal schemas to enforce that all properties are explicitly specified in the conversion. Future work: - better alignment of codegen with OpenAPI definitions of anyOf/oneOf. https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/#oneof oneOf requires that the input match exactly one schema from the list, which is different from z.union. anyOf should be z.union, oneOf should be z.discriminatedUnion - flatten the schema structure further to avoid `Type instantiation is excessively deep and possibly infinite`. Seems to be a common issue with zod (microsoft/TypeScript#34933) Limiting the number of `.merge` and other zod operations needed to build a particular schema object seems to help resolve the error. Combining `ResponseRequiredFields` and `ResponseOptionalFields` into a single object rather than merging them solved the immediate problem. However, we may still be near the depth limit. Changing `RuleResponse` as seen below also solved the problem in testing, and may give us more headroom for future changes if we apply techniques like this here and in other places. The difference here is that `SharedResponseProps` is only intersected with the type specific schemas after they're combined in a discriminated union, whereas in `main` we merge `SharedResponseProps` with each individual schema then merge them all together. - combine other Required and Optional schemas, like QueryRuleRequiredFields and QueryRuleOptionalFields ```ts export type RuleResponse = z.infer<typeof RuleResponse>; export const RuleResponse = SharedResponseProps.and(z.discriminatedUnion('type', [ EqlRuleResponseFields, QueryRuleResponseFields, SavedQueryRuleResponseFields, ThresholdRuleResponseFields, ThreatMatchRuleResponseFields, MachineLearningRuleResponseFields, NewTermsRuleResponseFields, EsqlRuleResponseFields, ])); ``` --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
One point in favor of upping the limit besides the weeks of my life wasted that I've spent battling these problems, is that I actually could easily speed up the tamagui types by 2x, except that it starts hitting complexity limits. So in fact the complexity limit is making things slower in practice rather than faster. |
The same issue I have using zod, did you find any workarounds for it? |
I got the same issue. Is there a workaround for this? |
What I interpret from this issue, and the comments within, is that that once your codebase/typing logic grows enough in size or complexity to an arbitrary point that TypeScript is unhappy with, you are no longer able to compile the project. So, am I correct to conclude from this, that TypeScript enforces an upper limit on the size of project that you are able to develop with it, and any larger/more complex projects are entirely unsupported by the compiler? Somebody please correct me if I am wrong, but the fact that you can spend years working on a project and one day hit an arbitrary "complexity limit" seems grossly incorrect and inappropriate for a tool of this breadth in the industry. If this is indeed the case, and I am not mistaken, then:
Open to input and corrections from others who have bumped into this. |
I think this really needs an option to just increase the size. The reason this is such a big problem is that - only the biggest projects are affected. IE, you've spent the most amount of effort investing into TypeScript, to the point where your types are really large. But now it actually comes around and bites you, and often in a way you just can't control. If a library you use everything in your project has complex types and you've used it 2k times across your codebase, and on the 2001 time it suddenly craps out, you're looking at losing type safety on one of your most critical/used pieces of the stack. The second reason I think we need a way around this is because the warning actually doesn't correlate with performance. I've landed big improvements to performance that caused this warning to occur. So it actually is a safeguard that is working against you oftentimes. |
Another person has said the same thing, over a year later, in 2020. These decisions seem a little short-sighted in hindsight, given that it's been five years, and that they have seemingly forgotten about this mechanism in its entirety.
I strongly resonate with this. It feels like a kick in the groin to hear that your usage of the system is outside of what they support, after investing so heavily in the ecosystem and the language itself.
This issue is only going to start popping up more and more, as more people start to get into codegen of complicated type systems. |
I get this issue all the time beacuse I'm using json-schema-to-ts It's documented in their FAQ, but there doesn't seem to be any fix |
More or less, the main problem with increasing type instantiation depth appears to be that some web instances of TypeScript just crash, because TypeScript is meant to be running everywhere apparently. |
Now I am curious if there is a limit to where TypeScript crashes simply because the compilation time exceeds an arbitrary "too long to compile" point. It seems strange that a long compilation time would force a crash, as opposed to a simple freeze. That seems like a separate issue in its entirety, unrelated to this one. I'm also not really sure who's compiling a project with 2000+ Zod usages in their browser at runtime... |
TypeScript Version: 3.7.2, 3.8.0-dev.20191102 (worked in 3.6)
Search Terms:
Code
Note: this issue manifests itself only in our codebase. When you run the same code in TypeScript Playground, it seems to be working fine.
The snippet is hardly minimal, but I reduced it as much as I could. I recorded a video where exactly the same code yields an error different than the one in TypeScript Playground. I tried with two versions of TypeScript:
3.7.2
and3.8.0-dev.20191102
. It worked correctly with3.6
.Since @sheetalkamat and @DanielRosenwasser have access to our repository, you're welcome to have a look at this PR. Copy-paste the code below anywhere in the project to see the error.
The versions of types used:
@types/history@4.7.3
@types/react@16.9.11
@types/react-router-dom@5.1.0
@types/recompose@0.30.7
Note: Interestingly enough, if you change:
it works again despite the fact
Omit<Props, never>
should be the same as justProps
.Source code
Expected behavior:
I should get a proper error about missing properties (not the one about type instantiation):
Actual behavior:
I'm getting this:
Playground Link:
Playground Link
Related Issues:
The text was updated successfully, but these errors were encountered: