Skip to content

tsc crashes with typescript@>4.0.0 #40239

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
anilanar opened this issue Aug 25, 2020 · 12 comments · Fixed by #40249
Closed

tsc crashes with typescript@>4.0.0 #40239

anilanar opened this issue Aug 25, 2020 · 12 comments · Fixed by #40249
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@anilanar
Copy link
Contributor

anilanar commented Aug 25, 2020

TypeScript Version: 4.1.0-dev.20200824

Search Terms: tsc cannot read property 'length' of undefined getResolvedMembersOrExportsOfSymbol symbol.declarations

Problem
tsc crashes after upgrading from 3.9.6 to 4.x.

Code

This problem happens after upgrading typescript on a project with 100k lines of code.
I don't have reproduction but I did my best to figure out what might be going wrong.

The crash stack trace:

TypeError: Cannot read property 'length' of undefined
    at getResolvedMembersOrExportsOfSymbol (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:41835:68)
    at getMembersOfSymbol (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:41868:19)
    at isEmptyAnonymousObjectType (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:46924:60)
    at addTypeToIntersection (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:44587:17)
    at addTypesToIntersection (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:44611:28)
    at getIntersectionType (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:44700:28)
    at instantiateTypeWorker (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:46192:25)
    at instantiateType (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:46166:26)
    at getReturnTypeOfSignature (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:43416:47)
    at checkCallExpression (/home/aanar/Development/Javascript/projects/Userlike/apps/umf/node_modules/typescript/lib/tsc.js:56186:30)

So the crash happens in the first line of the following for loop, while trying to iterate symbol.declarations which is undefined:

  for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
      var decl = _a[_i];
      var members = ts.getMembersOfDeclaration(decl);
      if (members) {
          for (var _b = 0, members_5 = members; _b < members_5.length; _b++) {
              var member = members_5[_b];
              if (isStatic === ts.hasStaticModifier(member) && hasLateBindableName(member)) {
                  lateBindMember(symbol, earlySymbols, lateSymbols, member);
              }
          }
      }
  }

I modified tsc.js to place some console.log statements. Right before the line that causes the crash:

  if (!symbol.declarations) {
    console.log(symbol);
  }

The result:

Symbol {
  flags: 33556480,
  escapedName: '__type',
  declarations: undefined,
  valueDeclaration: undefined,
  id: undefined,
  mergeId: undefined,
  parent: undefined,
  checkFlags: 0,
  type: Type {
    flags: 524288,
    id: 107,
    objectFlags: 16,
    symbol: [Circular *1],
    members: Map(1) { 'default' => [Symbol] },
    properties: [ [Symbol] ],
    callSignatures: [],
    constructSignatures: [],
    stringIndexInfo: undefined,
    numberIndexInfo: undefined
  },
  resolvedMembers: Map(0) {}
}

If I console.log(symbol.type.propertires) or symbol.type.members, I notice that it's pointing to @types/react-redux/index.d.ts.

It looks like it works when the for loop for symbol.declarations is wrapped with an if condition as below:

// The crash is due to `symbol.declarations` being undefined. So my naive workaround:
if (symbol.declarations) {
  for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
      var decl = _a[_i];
      var members = ts.getMembersOfDeclaration(decl);
      if (members) {
          for (var _b = 0, members_5 = members; _b < members_5.length; _b++) {
              var member = members_5[_b];
              if (isStatic === ts.hasStaticModifier(member) && hasLateBindableName(member)) {
                  lateBindMember(symbol, earlySymbols, lateSymbols, member);
              }
          }
      }
  }
}

If there's anything more I can help with, please let me know.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Aug 25, 2020
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.0.3 milestone Aug 25, 2020
@RyanCavanaugh
Copy link
Member

Thanks for the debugging on this!

@anilanar
Copy link
Contributor Author

anilanar commented Aug 25, 2020

Edit: Nevermind, I can reproduce this in dozens of other places.

Well, after some digging with try/catch and ts.getSourceFileOfNode, I figured out the file that causes it and created minimal (to my knowledge) reproduction.

It seems it has something to do with dynamic import and esModuleInterop.

Reproduction: https://github.com/anilanar/tscbug

"esModuleInterop": true stops the crashing.

@sandersn
Copy link
Member

sandersn commented Aug 25, 2020

Here's a standalone repro:

// @esModuleInterop: true
// @file:empty-export.d.ts
export {}
// @file:index.ts
declare function mock<M>(_: M): {} & M;
mock(await import('./empty-export'))

Edit: For me, I had to turn ON esModuleInterop. Here's the command line I'm using:

tsc --noemit --skiplibcheck --strict --esModuleInterop ~/src/test/index.ts

This was true for the tscbug repo as well.

@sandersn
Copy link
Member

sandersn commented Aug 25, 2020

The type is the shim type created for a module by esModuleInterop. It has an export named 'default' that's an alias for the empty-export module. However, the shim type's symbol has no declarations, is missing a bunch of other properties, but is marked with TypeLiteral flags (among others). I don't know what to make of it.

I'm not sure whether the shim type's symbol shouldn't be used anywhere, or whether the mapped type instantiation should be dereferencing or ignoring the shim, or whether the shim needs to better stand in for a real type/symbol. @weswigham any ideas?

@sandersn
Copy link
Member

PR that introduces this crash is #38673
@ahejlsberg

@weswigham
Copy link
Member

but is marked with TypeLiteral flags (among others)

Iirc, its marked as a literal because module objects get marked at literals so they can have inferred index signatures during assignment (since they're immutable). Honestly we should probably just err on the side of being better at handling a symbol without declarations more gracefully (the esmodule synthetic symbol is far from the only one without a declaration).

@artaommahe
Copy link

When new version with this fix will be released? Faced this crash while upgrading monorepo with angular projects to ng10 and ts 4.0.2..

@JackCA
Copy link

JackCA commented Sep 24, 2020

And FWIW, I'm still getting this on v4.0.3

@anilanar
Copy link
Contributor Author

@artaommahe @JackCA Please try beta which is prerelease 4.1.0.

@JackCA
Copy link

JackCA commented Oct 7, 2020 via email

@artaommahe
Copy link

artaommahe commented Oct 7, 2020

@anilanar cant use 4.1.x cause angular-cli 10.1.x does not support it. Also this issue marked as fixed by 4.0.3 (https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+4.0.3%22+is%3Aclosed+) but it's not, still crashing 😕

@zaunermax
Copy link

Maybe the info is relevant, but i also ran into this by adding the resolveJsonModule flag to the compile options and dynamically importing some JSON. Upgrading to Typescript 4.1.0-beta solved the issue 👍

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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants