This is a continuation of https://github.com/microsoft/TypeScript/issues/34869
I'm still getting the error testing against v3.8.0-dev.20191205
Here is my stack trace (the first one is react-styleguidist)
Trace
at withContext (node_modules/typescript/lib/typescript.js:36361:25)
at Object.typeToTypeNode (node_modules/typescript/lib/typescript.js:36316:28)
at typeToString (node_modules/typescript/lib/typescript.js:36283:40)
at Object.typeToString (node_modules/typescript/lib/typescript.js:33355:24)
at Parser.getDocgenType (node_modules/react-docgen-typescript/lib/parser.js:284:43)
at node_modules/react-docgen-typescript/lib/parser.js:331:29
at Array.forEach (<anonymous>)
at Parser.getPropsInfo (node_modules/react-docgen-typescript/lib/parser.js:309:27)
at Parser.getComponentInfo (node_modules/react-docgen-typescript/lib/parser.js:129:30)
at node_modules/react-docgen-typescript/lib/parser.js:702:27
at Array.map (<anonymous>)
at node_modules/react-docgen-typescript/lib/parser.js:701:14
at Array.reduce (<anonymous>)
at parseWithProgramProvider (node_modules/react-docgen-typescript/lib/parser.js:694:10)
at parse (node_modules/react-docgen-typescript/lib/parser.js:71:20)
at Object.module.exports (node_modules/react-styleguidist/lib/loaders/props-loader.js:41:12)
FAIL Failed to compile
[internal]
INTERNAL ERROR: Cannot read property 'valueDeclaration' of undefined
stack trace:
TypeError: Cannot read property 'valueDeclaration' of undefined
at getBaseConstructorTypeOfClass (node_modules/typescript/lib/typescript.js:40026:40)
at serializeAsClass (node_modules/typescript/lib/typescript.js:38036:42)
at serializeSymbolWorker (node_modules/typescript/lib/typescript.js:37770:29)
at serializeSymbol (node_modules/typescript/lib/typescript.js:37711:38)
at node_modules/typescript/lib/typescript.js:37686:25
at Map.forEach (<anonymous>)
at visitSymbolTable (node_modules/typescript/lib/typescript.js:37685:33)
at symbolTableToDeclarationStatements (node_modules/typescript/lib/typescript.js:37556:17)
at node_modules/typescript/lib/typescript.js:36340:106
at withContext (node_modules/typescript/lib/typescript.js:36362:37)
error Command failed with exit code 1.
Related Issues:
https://github.com/microsoft/TypeScript/issues/34869
@evenfrost @arian @BernsteinA @elibarzilay new issue here
@jasonwilliams how do we reproduce the issue?
@RyanCavanaugh thats what a few of us are trying to work out, this is happening on a large private repo which isn鈥檛 useful to you so the best I can provide is a stack trace.
From the last issue we are trying to narrow this down.
I've narrowed down the issue and it appears when using fork-ts-checker-webpack-plugin with webpack. If I remove ForkTsCheckerWebpackPlugin from my webpack plugins list, build runs without errors. It happens both in dev (with webpack-dev-server) and production build (when using webpack right away).
So after 4 hours of digging I've finally tracked down the issue (for me at least).
TL;DR: You should explicitly specify tsconfig option in ForkTsCheckerWebpackPlugin if you're using custom TS config file location.
Long story: I'm using webpack, ts-loader, fork-ts-checker-webpack-plugin and 2 separate TS config files (the one builds the client and is located in {project_root}/client/tsconfig.json, another one builds the server and is located in {project_root/tsconfig.json}). For client build I'm using ForkTsCheckerWebpackPlugin, which apparently has its own tsconfig option to specify custom tsconfig.json file path (which I thought would be inherited from configFile option of ts-loader). As I haven't specified tsconfig, fork-ts-checker-webpack-plugin took the config from {project_root/tsconfig.json}, which was server config, and ts-loader took it from correct location ({project_root}/client/tsconfig.json).
Don't know why it was working on TypeScript 3.6, but 3.7 release became really unhappy with it.
First off Happy New Year, back to debugging this.
@evenfrost explicitly specifying the tsconfig.json location didn't help me, i still get the same error.
However, like you said, removing the ForkTsCheckerWebpackPlugin from the webpack config removes the error.
Update:
I can get a successful build when i set useTypescriptIncrementalApi: false, within ForkTsCheckerWebpackPlugin settings.
Also, i have a better stack trace
TypeError: Cannot read property 'valueDeclaration' of undefined
at getBaseConstructorTypeOfClass (node_modules/typescript/lib/typescript.js:40017:40)
at serializeAsClass (node_modules/typescript/lib/typescript.js:38025:42)
at serializeSymbolWorker (node_modules/typescript/lib/typescript.js:37759:29)
at serializeSymbol (node_modules/typescript/lib/typescript.js:37700:38)
at node_modules/typescript/lib/typescript.js:37675:25
at Map.forEach (<anonymous>)
at visitSymbolTable (node_modules/typescript/lib/typescript.js:37674:33)
at symbolTableToDeclarationStatements (node_modules/typescript/lib/typescript.js:37545:17)
at node_modules/typescript/lib/typescript.js:36342:106
at withContext (node_modules/typescript/lib/typescript.js:36363:37)
at Object.symbolTableToDeclarationStatements (node_modules/typescript/lib/typescript.js:36342:28)
at Object.getDeclarationStatementsForSourceFile (node_modules/typescript/lib/typescript.js:64418:64)
at transformDeclarationsForJS (node_modules/typescript/lib/typescript.js:88026:35)
at transformRoot (node_modules/typescript/lib/typescript.js:88103:57)
at transformation (node_modules/typescript/lib/typescript.js:89306:24)
at transformRoot (node_modules/typescript/lib/typescript.js:89326:82)
at Object.map (node_modules/typescript/lib/typescript.js:543:29)
at Object.transformNodes (node_modules/typescript/lib/typescript.js:89313:30)
at emitDeclarationFileOrBundle (node_modules/typescript/lib/typescript.js:89891:43)
at emitSourceFileOrBundle (node_modules/typescript/lib/typescript.js:89800:13)
at forEachEmittedFile (node_modules/typescript/lib/typescript.js:89552:34)
at Object.emitFiles (node_modules/typescript/lib/typescript.js:89780:9)
at emitWorker (node_modules/typescript/lib/typescript.js:95796:33)
at node_modules/typescript/lib/typescript.js:95757:66
at runWithCancellationToken (node_modules/typescript/lib/typescript.js:95848:24)
at Object.emit (node_modules/typescript/lib/typescript.js:95757:20)
at Object.getFileEmitOutput (node_modules/typescript/lib/typescript.js:97391:34)
at updateShapeSignature (node_modules/typescript/lib/typescript.js:97637:39)
at Object.getFilesAffectedBy (node_modules/typescript/lib/typescript.js:97591:18)
at getNextAffectedFile (node_modules/typescript/lib/typescript.js:98062:51)
at getSemanticDiagnosticsOfNextAffectedFile (node_modules/typescript/lib/typescript.js:98584:32)
at Object.getSemanticDiagnostics (node_modules/typescript/lib/typescript.js:98628:20)
at emitFilesAndReportErrors (node_modules/typescript/lib/typescript.js:99945:54)
at Object.result.afterProgramCreate (node_modules/typescript/lib/typescript.js:100137:13)
at CompilerHost.afterProgramCreate (node_modules/fork-ts-checker-webpack-plugin/lib/CompilerHost.js:249:21)
at synchronizeProgram (node_modules/typescript/lib/typescript.js:100380:22)
at Object.createWatchProgram (node_modules/typescript/lib/typescript.js:100326:9)
at CompilerHost.<anonymous> (node_modules/fork-ts-checker-webpack-plugin/lib/CompilerHost.js:76:48)
at Generator.next (<anonymous>)
at node_modules/fork-ts-checker-webpack-plugin/lib/CompilerHost.js:7:71
at new Promise (<anonymous>)
at __awaiter (node_modules/fork-ts-checker-webpack-plugin/lib/CompilerHost.js:3:12)
at CompilerHost.processChanges (node_modules/fork-ts-checker-webpack-plugin/lib/CompilerHost.js:64:16)
at ApiIncrementalChecker.<anonymous> (node_modules/fork-ts-checker-webpack-plugin/lib/ApiIncrementalChecker.js:68:66)
at Generator.next (<anonymous>)
at node_modules/fork-ts-checker-webpack-plugin/lib/ApiIncrementalChecker.js:7:71
at new Promise (<anonymous>)
at __awaiter (node_modules/fork-ts-checker-webpack-plugin/lib/ApiIncrementalChecker.js:3:12)
at ApiIncrementalChecker.getDiagnostics (node_modules/fork-ts-checker-webpack-plugin/lib/ApiIncrementalChecker.js:67:16)
at node_modules/fork-ts-checker-webpack-plugin/lib/service.js:88:41
at Generator.next (<anonymous>)
at node_modules/fork-ts-checker-webpack-plugin/lib/service.js:7:71
at new Promise (<anonymous>)
at __awaiter (node_modules/fork-ts-checker-webpack-plugin/lib/service.js:3:12)
at run (node_modules/fork-ts-checker-webpack-plugin/lib/service.js:83:12)
at Object.run (node_modules/fork-ts-checker-webpack-plugin/lib/service.js:112:7)
at RpcProvider._handeRpc (node_modules/worker-rpc/lib/RpcProvider.js:106:54)
at RpcProvider.dispatch (node_modules/worker-rpc/lib/RpcProvider.js:22:29)
at process.<anonymous> (node_modules/fork-ts-checker-webpack-plugin/lib/service.js:33:38)
at process.emit (events.js:210:5)
at emit (internal/child_process.js:878:12)
at processTicksAndRejections (internal/process/task_queues.js:81:21)
Using
I've ran git bisect against commits between v3.6.4 (where it works) and v3.7-rc (where it fails).
The offending commit seems to be this one
https://github.com/microsoft/TypeScript/commit/29becf05012bfa7ba20d50b0d16813971e46b8a6
@RyanCavanaugh does any of this help?
@evenfrost seeing as we're getting different results could you share your working tsconfig file?
@jasonwilliams here's mine:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./*"
]
},
"module": "commonjs",
"outDir": "./build",
"rootDir": "./",
"target": "es2019"
},
"exclude": [
"./build/**/*",
"./client/**/*",
"node_modules",
"**/node_modules/*"
]
}
Content of tsconfig.base.json:
{
"compilerOptions": {
"allowUnreachableCode": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": false,
"removeComments": true,
"sourceMap": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true
}
}
Thanks I鈥檒l compare against mine
@evenfrost did you try setting useTypescriptIncrementalApi: false in your typescript checker settings?
The stack trace might be enough to go on. We'll give it a shot.
@RyanCavanaugh @rbuckton i've managed to create a test case here:
https://github.com/jasonwilliams/typescript-35801-testcase
Hi there, I also created minimal set for the reproduction.
create index.js with
let A;
A = {};
A.prototype.b = {}
in empty directory.
tsc --allowJs --declaration index.jsIt throws like:
/usr/lib/node_modules/typescript/lib/tsc.js:81040
throw e;
^
TypeError: Cannot read property 'valueDeclaration' of undefined
at getBaseConstructorTypeOfClass (/usr/lib/node_modules/typescript/lib/tsc.js:34146:40)
at serializeAsClass (/usr/lib/node_modules/typescript/lib/tsc.js:32403:42)
at serializeSymbolWorker (/usr/lib/node_modules/typescript/lib/tsc.js:32202:29)
at serializeSymbol (/usr/lib/node_modules/typescript/lib/tsc.js:32159:38)
at /usr/lib/node_modules/typescript/lib/tsc.js:32140:25
at Map.forEach (<anonymous>)
at visitSymbolTable (/usr/lib/node_modules/typescript/lib/tsc.js:32139:33)
at symbolTableToDeclarationStatements (/usr/lib/node_modules/typescript/lib/tsc.js:32031:17)
at /usr/lib/node_modules/typescript/lib/tsc.js:30890:106
at withContext (/usr/lib/node_modules/typescript/lib/tsc.js:30910:37)
My tsc is v3.8.3.
I hope this helps you.
This may be related to #36273.
@weswigham I have a fix for the crash, but I'm not sure I like the JS declaration emit for @acomagu's example:
// js
let A;
A = {};
A.prototype.b = {};
// .d.ts
declare class A {
b: {};
}
The binder declares A as both a FunctionScopedVariable (because of the let) and a Class because of the prototype assignment heuristic. The binder can't know whether its actually a class, so should we be doing some additional work in serializeSymbolWorker to exclude non-class-like symbols (i.e., check that it has both SymbolFlags.Class and some kind of call or construct signature)?
I'm thinking about something like this:
function isEffectiveClassSymbol(symbol: Symbol) {
if (!(symbol.flags & SymbolFlags.Class)) {
return false;
}
if (isInJSFile(symbol.valueDeclaration) && !isClassLike(symbol.valueDeclaration)) {
// For a symbol that isn't syntactically a `class` in a JS file we have heuristics
// that detect prototype assignments that indicate the symbol is *probably* a class.
// Filter out any prototype assignments for non-class symbols, i.e.
//
// let A;
// A = {};
// A.prototype.b = {};
const type = getTypeOfSymbol(symbol);
return some(getSignaturesOfType(type, SignatureKind.Construct))
|| some(getSignaturesOfType(type, SignatureKind.Call));
}
return true;
}
Hmm, seems reasonable.
One note: not sure if this was stated, but I only ran into this issue with using tsc -b. The tsc -p option didn't have this issue. So (for me) it's only an issue when using the build mode.
Also seeing something similar when converting a vanilla js (does use jsdoc) project over to ts 3.9.4.
tsc works, but tsc -w does not.
downgrading to 3.6.4 and tsc -w does work.
This was fixed in #38508.
Most helpful comment
This was fixed in #38508.