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

"Type instantiation is excessively deep" for Element as a predicant #6

Open
devanshj opened this issue Jul 21, 2022 · 6 comments
Open

Comments

@devanshj
Copy link
Owner

devanshj commented Jul 21, 2022

import { p, pa } from "@sthir/predicate"

pa({} as Element, p())
//                ~~~
// Type instantiation is excessively deep and possibly infinite.(2589)

Not sure why it's happening, possibly because Element has many keys... If that's the reason then we need to figure out a test for type with many keys (or union with many constituents) and then don't compute index operator for them (which means now .parentNode, .children, etc won't show up in the intellisense completetion) and only validate it.

@devanshj devanshj changed the title bug(predicate): "Type instantiation is excessively deep" on big predicants "Type instantiation is excessively deep" on big predicants Jul 21, 2022
@devanshj
Copy link
Owner Author

devanshj commented Jul 21, 2022

I think we can find if a union has many constituents (say more than 15) using something like this...

namespace U {
  type HasManyConstituents<U, L = 15> =
    U extends never ? false :
    L extends 0 ? true :
    HasManyConstituents<U.Pop<U>, N.Decrement<L>>
}

And later we could even take the upper limit from some "options interface" via module augumentation instead of keeping it a hardcoded 15.

Also I wonder if it's possible make sense to show only top 15 keys as completion but also have a .${string} that we later validate, so like ".parentNode" | ".children" | `.${string}` (with validation for `.${string}`)

@devanshj
Copy link
Owner Author

Another much greater possibility is that (afair) we compute index operator deeply (and eagerly) and Element has a recursive definition hence we get an infinite recursion. In that case we should just not compute the index operator eagerly for all cases (or maybe not just in cases where predicant has a recursive definition)

@devanshj
Copy link
Owner Author

devanshj commented Jul 22, 2022

Yep, looks like it's because of recursive definition...

import { p, pa } from "@sthir/predicate"

interface MyElement {
  parentElement: MyElement
}

pa({} as MyElement, p())
//                  ~~~
// Type instantiation is excessively deep and possibly infinite.(2589)

In that case let's do this...

In that case we should just not compute the index operator eagerly for all cases (or maybe not just in cases where predicant has a recursive definition)

@devanshj devanshj changed the title "Type instantiation is excessively deep" on big predicants Support predicants with recursive type definition Jul 22, 2022
@devanshj devanshj changed the title Support predicants with recursive type definition "Type instantiation is excessively deep" for Element as a predicant Jul 22, 2022
@devanshj
Copy link
Owner Author

I'm too lazy to rewrite the types right now to make index not compute eagerly, so instead in case of recursive types we stop when we come across a type we've already seen and with that we fixed #8

This comes with a little downside that instead of being able to write pa(e, p(".parentElement.parentElement.innerHTML")) you'll have to write pa(e, p(".parentElement .parentElement.innerHTML")) basically you'll have to break the index operator at the point of recursion.

But even after fixing #8 the code in the description takes too long (and probably also shows the error didn't wait to see it) that's probably because as we're still computing (deep) index eagerly and Element is huge af.

Now to fix Element scenario and also remove the breaking-at-point-of-recursion workaround we'll have to have non-eager index operator.

We can also try another solution of checking when a type is huge and making users break the index operator at every level (p(".a .b .c") instead of p(".a.b.c")), that might be easier.

@devanshj
Copy link
Owner Author

e4dfae5 — Pretty weird even with PathShallow we still get the "Type instantiation is excessively deep" error. This will require more investigation lmao.

@devanshj
Copy link
Owner Author

Ah maybe I.Intersect also needs to deal with recursive definitions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant