Skip to content

Stack overflow related to "getting" awaited, recursive union type #42948

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

Closed
DuncanWalter opened this issue Feb 24, 2021 · 2 comments · Fixed by #51167
Closed

Stack overflow related to "getting" awaited, recursive union type #42948

DuncanWalter opened this issue Feb 24, 2021 · 2 comments · Fixed by #51167
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@DuncanWalter
Copy link

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 😄

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Feb 25, 2021
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.3.0 milestone Feb 25, 2021
@akutruff
Copy link

akutruff commented 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

/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:88055
                throw e;
                ^
RangeError: Maximum call stack size exceeded
    at createBaseNode (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:16664:32)
    at Object.createInferTypeNode (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:17463:24)
    at typeToTypeNodeHelper (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39163:43)
    at mapToTypeNodes (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39674:40)
    at typeReferenceToTypeNode (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39462:49)
    at typeToTypeNodeHelper (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39158:95)
    at typeToTypeNodeHelper (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39227:43)
    at mapToTypeNodes (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39674:40)
    at typeToTypeNodeHelper (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39150:45)
    at typeToTypeNodeOrCircularityElision (/usr/local/share/npm-global/lib/node_modules/typescript/lib/tsc.js:39250:28)

@DanielRosenwasser
Copy link
Member

Thanks @Andarist!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants