-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Excessive Stack Depth from DeepPartial/RecursivePartial in 2.7.x #21592
Comments
I got the same code with the next code: type SafeAny <T> = {
[k in keyof T]?: SafeAny<T[k]>
} | boolean | number | string | symbol | null | undefined
type DataValidator <T> = {
[k in keyof T]?: (v: SafeAny<T[k]>) => v is T[k]
} The following error is reported:
@kevinbeal |
@Conaclos In what sense exactly is the link wrong? I did hit "share". It wouldn't be a really long URL with url encoded typescript in the URL if I hadn't. Are you not seeing the issue when you click the link? |
@kevinbeal |
From bisecting, the bad commit is part of #19564. |
Recursive mapped types usually lead to the error "excess stack depth comparing types" because of a new type relation rule added in #19564 which says that "A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X". Unfortunately, with self-recursive mapped types like ```ts D<T> = { [P in keyof T]: D<T[P]> } ``` we get infinite recursion when trying to assign a type parameter T to D<T>, as T[P] is compared to D<T[P]>, T[P][P] is compared to D<T[P][P]>, and so on. We can avoid many of these infinite recursions by replacing occurrences of D in the template type with its type argument. This works because mapped types will completely cover the tree, so checking assignability of the top level implies that checking of lower level would succeed, even if there are infinitely many levels. For example: ```ts D<T> = { [P in keyof T]: D<T[P]> | undefined } <T>(t: T, dt: D<T>) => { dt = t } ``` would previously check that `T[P]` is assignable to `D<T[P]> | undefined`. Now, after replacement, it checks that `T[P]` is assignable to `T[P] | undefined`. This implementation suffers from 3 limitations: 1. I use aliasSymbol to detect whether a type reference is a self-recursive one. This only works when the mapped type is at the top level of a type alias. 2. Not all instances of D<T> are replaced with T, just those in intersections and unions. I think this covers almost all uses. 3. This doesn't fix #21048, which tries to assign an "off-by-one" partial-deep type to itself. Mostly fixes #21592. One repro there has a type alias to a union, and a mapped type is a member of the union. But this can be split into two aliases: ```ts type SafeAnyMap<T> = { [K in keyof T]?: SafeAny<T[K] }; type SafeAny<T> = SafeAnyMap<T> | boolean | string | symbol | number | null | undefined; ```
I am using TypeScript 2.9.1 and still the same issue. |
@chirdeeptomar this issue was assigned to the 3.0 milestone |
Running into the same issue with Example:
This actually results in excessive stack depth on both the second and third params of
This has gotten worse in one of the more recent TypeScript versions; with Seems like this is a difficult problem on TypeScript's end so hopefully this workaround is useful to someone else in the meantime... Is this something I should be raising with the Redux maintainers? |
@hswhite33 Yes, the Redux maintainers should first consider whether they need the additional type safety or inference information that comes from DeepPartial. Redux users probably don't rely on it that much, actually. If they want to keep it, they can use the workaround above, although it might break in future Typescript versions. |
…t with typeorm. fixes error TS2321: Excessive stack depth comparing types 'any' and 'FindConditions<T>' More context on the issue: microsoft/TypeScript#21592 (comment) Related PR: typeorm#4470
…#35848) * Remove PartialDeep from lodash, replace w/Partial Fixes the most common occurrence of microsoft/TypeScript#21592. I don't think anybody uses the full capability of `PartialDeep` as a parameter, and it doesn't really make sense as the return type of `pick`. * Use PartialObject name instead of GlobalPartial
I won but disappointed. 😭 Now my questions is: Will it be moved to 3.7.0 😿 ? Should I bet 10$ ? |
error TS2321: Excessive stack depth comparing types 'DataObject<?>' and 'DataObject<?>'. See microsoft/TypeScript#21592
Just got hit by this in TS 3.6.2 which Renovate bot just attempted to update to and our pipeline failed. ): It's not even our own code. It comes from one of the libraries that we use:
|
error TS2321: Excessive stack depth comparing types 'DataObject<?>' and 'DataObject<?>'. See microsoft/TypeScript#21592
Is it a bug in TypeScript compiler or just libraries' code is faulty? Maybe TS team should come up with some guidance how to write code to avoid this bug if it's not an issue with tsc itself. It's really frustrating that it didn't get fixed yet |
error TS2321: Excessive stack depth comparing types 'DataObject<?>' and 'DataObject<?>'. See microsoft/TypeScript#21592
error TS2321: Excessive stack depth comparing types 'DataObject<?>' and 'DataObject<?>'. See microsoft/TypeScript#21592
@alfaproject you have a different issue. Notice that the two types are the same in your case. This is a known bug (#33132) with a fix at #33144. We'll ship it in 3.6.3 in the next week or so. |
I hate this bug. The only thing is work agains it is |
this was added to our typing to work around issue described in microsoft/TypeScript#21592 - however, as of TS 3.6.3 it has not been an issue
this was added to our typing to work around issue described in microsoft/TypeScript#21592 - however, as of TS 3.6.3 it has not been an issue
this was added to our typing to work around the issue described in microsoft/TypeScript#21592 - however, as of TS 3.6.3 it has not been a problem
Fixed in 3.7 |
Search Terms:
"excessive depth"
"generic partial"
Code
Expected behavior:
Comparing a generic with a partial of that generic working without errors.
Actual behavior:
Getting "Excessive stack depth comparing types 'T' and 'RecursivePartial'." since upgrading to 2.7.x. (Also errors in 2.8.x). Working in 2.6.1.
Playground Link:
https://www.typescriptlang.org/play/index.html#src=class%20Greeter%20%7B%0D%0A%20%20%20%20greeting%3A%20RecursivePartial%3Cstring%3E%3B%0D%0A%20%20%20%20constructor(message%3A%20string)%20%7B%0D%0A%20%20%20%20%20%20%20%20this.greeting%20%3D%20message%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20greet()%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20%22Hello%2C%20%22%20%2B%20this.greeting%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Alet%20greeter%20%3D%20new%20Greeter(%22world%22)%3B%0D%0A%0D%0Alet%20button%20%3D%20document.createElement('button')%3B%0D%0Abutton.textContent%20%3D%20%22Say%20Hello%22%3B%0D%0Abutton.onclick%20%3D%20function()%20%7B%0D%0A%20%20%20%20alert(greeter.greet())%3B%0D%0A%7D%0D%0A%0D%0Adocument.body.appendChild(button)%3B%0D%0A%0D%0Aconst%20fn%20%3D%20%3CT%3E(arg%3A%20T)%20%3D%3E%20%7B%0D%0A%20%20%20%20((arg2%3A%20RecursivePartial%3CT%3E)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20%20%20%2F%2F%0D%0A%20%20%20%20%7D)(arg)%3B%0D%0A%7D%3B%0D%0A%0D%0Atype%20RecursivePartial%3CT%3E%20%3D%20%7B%0D%0A%20%20%20%20%5BP%20in%20keyof%20T%5D%3F%3A%20RecursivePartial%3CT%5BP%5D%3E%3B%0D%0A%7D%3B
Related Issues:
None?
The text was updated successfully, but these errors were encountered: