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

keyof and type parameters can produce huge types that hang/crash compiler #25942

Closed
mattmccutchen opened this issue Jul 25, 2018 · 2 comments
Closed
Labels
Bug A bug in TypeScript
Milestone

Comments

@mattmccutchen
Copy link
Contributor

Somehow, while writing real code, I stumbled upon this combination of constructs that seems to quickly produce huge types that hang or crash the compiler. I suggest that there should be some limit on type size at which the compiler gives up rather than potentially hanging/crashing, in the spirit of the limit of 100 on the depth of some existing operations in the checker.

TypeScript Version: master (2e89dbd)

Search Terms: keyof type parameter variable large type hang crash out of memory

Code

interface JSONableArray extends Array<JSONable> {}
interface JSONableDict {
  [key: string]: JSONable;
}
type JSONable = number | string | boolean | JSONableArray | JSONableDict;

function foo<T>(t: T): Pick<T, Exclude<keyof T, "foo">> & JSONable {
  throw new Error("not implemented");
}

function test<T>(t: T) {
  let t1 = foo(t);
  let t2 = foo(t1);
  let t3 = foo(t2);
  let y: number = "hello";
}

Expected behavior: Compiler hits some safety limit on t3 and goes on to report the error on y.

Actual behavior: Compiler runs out of memory. In VS Code, the language service runs out of memory, crashes, restarts, runs out of memory, crashes, etc., and never reports the error on y. This is a poor user experience.

Playground Link: may crash your browser

Related Issues: #24223. I originally thought my case was covered by #24223, but it isn't: #24223 is about a better algorithm to simplify a type that ends up being reasonable in size, while in my case, the fully simplified type is huge.

@RyanCavanaugh
Copy link
Member

It's problematic. This type isn't infinitely expanding in a way that triggers any of our depth checks, and doesn't really look to the checker like a problematic type in a way that we understand how to detect.

We discussed a bunch of ideas for how to deal with this but didn't come up with anything that wasn't likely to trigger false positives in working code. It's possible there's something... we just haven't found it yet.

Our only real answer at the moment is "don't write code like that" and we're just hoping for a better way to communicate that answer to the developer than hanging or crashing. Still a bug but we don't have an immediate answer.

@jakebailey
Copy link
Member

Just looking at ancient issues; this one was fixed in #31572 with a new limiter.

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

No branches or pull requests

5 participants