-
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
Type instantiation is excessively deep with PartialRecursive & recursive list type #35156
Comments
Related: #33050, which introduced the ability to write |
Looking at this some more I noticed that the problem is in my own (probably copied from somewhere) This fixes my case: type PartialRecursive<T> = T extends object
? T extends Array<infer U> ? PartialRecursive<U>[]
: { [K in keyof T]?: PartialRecursive<T[K]> }
: T |
I wouldn't be so quick to dismiss this; since TypeScript 3.1, mapped array/tuple types have been supported so you shouldn't have to special-case arrays like that. Indeed, the pre-TS-3.7 way of typing type Json =
| string
| number
| boolean
| null
| { [property: string]: Json }
| JsonArray
interface JsonArray extends Array<Json> {}
type PartialRecursive<T> = T extends object
? { [K in keyof T]?: PartialRecursive<T[K]> }
: T
interface Data {
value: Json
}
function acceptData(param: PartialRecursive<Data>) {}
const data = {} as Data
acceptData(data) // no error So whatever's going on here isn't what I'd call a problem with recursive mapped types. I don't know if this is a compiler bug / design limitation / working as intended, but I'm still interested in seeing what an official word here would be. |
Re-opening, feel free to close if this works as expected |
This is effectively a design limitation. When a homomorphic mapped type is applied to an array type, we obtain the element type of the array and apply the mapped type's template type to that. This is done eagerly, which effectively causes a circularity when the type being mapped is itself circular. As mentioned above, the original example works when an array case is added to the conditional type: type PartialRecursive<T> =
T extends (infer U)[] ? PartialRecursive<U>[] :
T extends object ? { [K in keyof T]?: PartialRecursive<T[K]> } :
T; Here, |
TypeScript Version: 3.7.2 (and nightly/next)
Search Terms:
Type instantiation is excessively deep and possibly infinite
Code
Expected behavior:
Value field should be valid as both the type itself is already inferred as the
Data
type and the entire type is optionalActual behavior:
The recursive list type causes an infinite (or excessive) calculation that fails.
Playground Link:
Related Issues:
error TS2321: Excessive stack depth comparing types 'Function<?>' and 'Function<?>'.
#33132The text was updated successfully, but these errors were encountered: