Repository navigation
Stack overflow related to "getting" awaited, recursive union type #42948
Description
Bug Report
Hit a stack overflow that seems like a member of this family of previously reported + solved issue.
🔎 Search Terms
stack limit mapType getAwaitedType getAwaitedTypeWorker
🕗 Version & Regression Information
Seems to have existed since ~3.7 when the type keyword began to support self references. The playground link is for the nightly. I had to open the dev tools to see the actual crash message in the playground.
⏯ Playground Link
Playground link with relevant code
💻 Code
type EffectResult =
| (() => EffectResult)
| Promise<EffectResult>;
export async function handleEffectResult(result: EffectResult) {
if (result instanceof Function) {
await handleEffectResult(result());
} else if (result instanceof Promise) {
await handleEffectResult(await result);
}
}🙁 Actual behavior
RangeError: Maximum call stack size exceeded
at /absolute-path/node_modules/typescript/lib/tsc.js:59379:52
at mapType (/absolute-path/node_modules/typescript/lib/tsc.js:50800:30)
at getAwaitedType (/absolute-path/node_modules/typescript/lib/tsc.js:59379:17)
at getAwaitedTypeWorker (/absolute-path/node_modules/typescript/lib/tsc.js:59395:35)
at /absolute-path/node_modules/typescript/lib/tsc.js:59379:79
at mapType (/absolute-path/node_modules/typescript/lib/tsc.js:50800:30)
at getAwaitedType (/absolute-path/node_modules/typescript/lib/tsc.js:59379:17)
at getAwaitedTypeWorker (/absolute-path/node_modules/typescript/lib/tsc.js:59395:35)
at /absolute-path/node_modules/typescript/lib/tsc.js:59379:79
at mapType (/absolute-path/node_modules/typescript/lib/tsc.js:50800:30)
error Command failed with exit code 1.
🙂 Expected behavior
In hindsight that code is pretty sadistically self-referential, but I didn't expect to hit an overflow limit. Ideally the code sample should check without any issue. Alternatively, some warning to indicate which lines of code are involved in process crash would be plenty; this type of nightmare-recursion should be an edge case, and there's a decent workaround. This edited sample is fine for the same range of versions from 3.7 to the nightly build:
type Effect = () => EffectResult
type EffectResult =
| Effect
| Promise<Effect>;
export async function handleEffectResult(result: EffectResult) {
if (result instanceof Function) {
await handleEffectResult(result());
} else if (result instanceof Promise) {
await handleEffectResult(await result);
}
}Thanks in advance for taking a look 😄
Activity
akutruff commentedon Mar 16, 2021
Hitting a stack overflow too. It's not promise related, but maybe this call stack helps. My code is also heavily self-referential and heavily uses recursive conditional types
Compiled with 4.2.3
DanielRosenwasser commentedon Oct 28, 2022
Thanks Mateusz Burzyński (@Andarist)!