Description
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.