Repository navigation
Maximum call stack size exceeded while inferring conditional type. #22950
Copy link
Copy link
Closed
Labels
BugA bug in TypeScriptA bug in TypeScriptFixedA PR has been merged for this issueA PR has been merged for this issue
Milestone
Description
TypeScript Version: 2.9.0-dev.20180328
The code below fails with a "Maximum call stack size exceeded" error. I actually came across this while trying to make a minimal example of a separate problem which is why the code looks so useless.
Code
type AProp<T extends { a: string }> = T
declare function myBug<
T extends { [K in keyof T]: T[K] extends AProp<infer U> ? U : never }
>(arg: T): T
const out = myBug({obj1: {a: "test"}})Additional similar case that started crashing later. Following code does not crash in 2.8.1 but does in typescript@next
type Value<V extends string = string> = Record<"val", V>;
declare function value<V extends string>(val: V): Value<V>;
declare function ensureNoDuplicates<
T extends {
[K in keyof T]: Extract<T[K], Value>["val"] extends Extract<T[Exclude<keyof T, K>], Value>["val"]
? never
: any
}
>(vals: T): void;
const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2")});
const shouldBeNoError = ensureNoDuplicates({main: value("test")});
const shouldBeError = ensureNoDuplicates({main: value("dup"), alternate: value("dup")});Actual behavior:
[Error - 09:54:19] 'quickinfo' request failed with error.
Error processing request. Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
at resolveEntityName (tsserver.js:22816:35)
at getSymbolOfEntityNameOrPropertyAccessExpression (tsserver.js:40471:24)
at getSymbolAtLocation (tsserver.js:40512:28)
at getTypeFromTypeNode (tsserver.js:28216:34)
at containsReference (tsserver.js:28397:79)
at visitNode (tsserver.js:12757:24)
at Object.forEachChild (tsserver.js:12867:24)
at containsReference (tsserver.js:28401:27)
at visitNode (tsserver.js:12757:24)
at Object.forEachChild (tsserver.js:12894:24)
at containsReference (tsserver.js:28401:27)
at visitNode (tsserver.js:12757:24)
at Object.forEachChild (tsserver.js:12884:24)
at isTypeParameterPossiblyReferenced (tsserver.js:28388:31)
at tsserver.js:27929:146
at Object.filter (tsserver.js:1671:31)
at getTypeFromConditionalTypeNode (tsserver.js:27929:92)
at getTypeFromTypeNode (tsserver.js:28211:28)
at getTemplateTypeFromMappedType (tsserver.js:26007:52)
at substituteIndexedMappedType (tsserver.js:27818:36)
at getSimplifiedIndexedAccessType (tsserver.js:27810:28)
at getConstraintOfIndexedAccess (tsserver.js:26146:31)
at getConstraintOfType (tsserver.js:26138:40)
at getConstraintForRelation (tsserver.js:29333:80)
at structuredTypeRelatedTo (tsserver.js:29404:38)
at recursiveTypeRelatedTo (tsserver.js:29315:53)
at isRelatedTo (tsserver.js:29031:38)
at checkTypeRelatedTo (tsserver.js:28882:26)
at isTypeRelatedTo (tsserver.js:28864:24)
at Function.compareTypesAssignable [as compareTypes] (tsserver.js:28584:20)
at getInferredType (tsserver.js:30913:34)
at mapper (tsserver.js:30436:32)
at instantiateType (tsserver.js:28464:28)
at getConditionalType (tsserver.js:27888:60)
at getTypeFromConditionalTypeNode (tsserver.js:27943:38)
at getTypeFromTypeNode (tsserver.js:28211:28)
at getTemplateTypeFromMappedType (tsserver.js:26007:52)
at substituteIndexedMappedType (tsserver.js:27818:36)
at getSimplifiedIndexedAccessType (tsserver.js:27810:28)
at getConstraintOfIndexedAccess (tsserver.js:26146:31)
at getConstraintOfType (tsserver.js:26138:40)
at getConstraintForRelation (tsserver.js:29333:80)
at structuredTypeRelatedTo (tsserver.js:29404:38)
at recursiveTypeRelatedTo (tsserver.js:29315:53)
at isRelatedTo (tsserver.js:29031:38)
at checkTypeRelatedTo (tsserver.js:28882:26)
at isTypeRelatedTo (tsserver.js:28864:24)
at Function.compareTypesAssignable [as compareTypes] (tsserver.js:28584:20)
at getInferredType (tsserver.js:30913:34)
at mapper (tsserver.js:30436:32)
at instantiateType (tsserver.js:28464:28)
at getConditionalType (tsserver.js:27888:60)
at getTypeFromConditionalTypeNode (tsserver.js:27943:38)
at getTypeFromTypeNode (tsserver.js:28211:28)
at getTemplateTypeFromMappedType (tsserver.js:26007:52)
at substituteIndexedMappedType (tsserver.js:27818:36)
at getSimplifiedIndexedAccessType (tsserver.js:27810:28)
at getConstraintOfIndexedAccess (tsserver.js:26146:31)
at getConstraintOfType (tsserver.js:26138:40)
at getConstraintForRelation (tsserver.js:29333:80)
at structuredTypeRelatedTo (tsserver.js:29404:38)
at recursiveTypeRelatedTo (tsserver.js:29315:53)
at isRelatedTo (tsserver.js:29031:38)
at checkTypeRelatedTo (tsserver.js:28882:26)
at isTypeRelatedTo (tsserver.js:28864:24)
at Function.compareTypesAssignable [as compareTypes] (tsserver.js:28584:20)
at getInferredType (tsserver.js:30913:34)
at mapper (tsserver.js:30436:32)
at instantiateType (tsserver.js:28464:28)
at getConditionalType (tsserver.js:27888:60)
at getTypeFromConditionalTypeNode (tsserver.js:27943:38)
at getTypeFromTypeNode (tsserver.js:28211:28)
at getTemplateTypeFromMappedType (tsserver.js:26007:52)
at substituteIndexedMappedType (tsserver.js:27818:36)
at getSimplifiedIndexedAccessType (tsserver.js:27810:28)
at getConstraintOfIndexedAccess (tsserver.js:26146:31)
at getConstraintOfType (tsserver.js:26138:40)
at getConstraintForRelation (tsserver.js:29333:80)
at structuredTypeRelatedTo (tsserver.js:29404:38)
at recursiveTypeRelatedTo (tsserver.js:29315:53)
at isRelatedTo (tsserver.js:29031:38)
at checkTypeRelatedTo (tsserver.js:28882:26)
at isTypeRelatedTo (tsserver.js:28864:24)
at Function.compareTypesAssignable [as compareTypes] (tsserver.js:28584:20)
at getInferredType (tsserver.js:30913:34)
at mapper (tsserver.js:30436:32)
at instantiateType (tsserver.js:28464:28)
at getConditionalType (tsserver.js:27888:60)
at getTypeFromConditionalTypeNode (tsserver.js:27943:38)
at getTypeFromTypeNode (tsserver.js:28211:28)
at getTemplateTypeFromMappedType (tsserver.js:26007:52)
at substituteIndexedMappedType (tsserver.js:27818:36)
at getSimplifiedIndexedAccessType (tsserver.js:27810:28)
at getConstraintOfIndexedAccess (tsserver.js:26146:31)
at getConstraintOfType (tsserver.js:26138:40)
at getConstraintForRelation (tsserver.js:29333:80)
at structuredTypeRelatedTo (tsserver.js:29404:38)
at recursiveTypeRelatedTo (tsserver.js:29315:53)
at isRelatedTo (tsserver.js:29031:38)
at checkTypeRelatedTo (tsserver.js:28882:26)
Playground Link:
Link
Related Issues:
Multiple "Maximum call stack size exceeded" issues exist but looking at the recent ones I did not notice any that were obvious duplicates.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptFixedA PR has been merged for this issueA PR has been merged for this issue
Activity
mhegazy commentedon Mar 28, 2018
I am not sure why you are writing a constraint this way, it seems to me that this should just be
declare function myBug<T extends Record<string, {a:string}>>(arg: T): T, on any rate, we should not crash.kpdonn commentedon Mar 28, 2018
Agreed the code isn’t meaningful at all. I was in the process of writing something longer that wouldn’t have been so pointless when I stumbled onto this crash and figured the crash was a bug regardless of the code.
mhegazy commentedon Mar 28, 2018
constraining a generic type of a mapped type on itself is not that useful of a patter i would say.
kpdonn commentedon Mar 29, 2018
You'd be surprised then. I've been using the pattern to successfully create compile errors if duplicate keys are found in an api that shouldn't accept duplicates.
Simple-ish example I came up with from #22679:
Playground Link
And it's not ready for anyone to use or even really read yet but I've been experimenting with more complicated use cases that might end up being very practical: Example
Cryrivers commentedon May 9, 2018
Here's a meaningful case that triggers
Maximum call stack size exceededin TypeScript 2.9 Dev.https://github.com/DefinitelyTyped/DefinitelyTyped/blob/65b176eaefc9a53c8e9cc615d290cb927947a6bb/types/react-redux/index.d.ts#L66
tsccrashes unless the conditional type is removed.Cryrivers commentedon May 23, 2018
Update: I believe this bug has been fixed in 2.9.1 insiders build.