You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[api-extractor] Error: Symbol not found for identifier: Readonly #1304
We're using api-extractor at decentraland/explorer. We've tried updating TS to version 3.4 to make use of incremental builds but we just got this not-friendly error:
api-extractor 7.1.6 - https://api-extractor.com/
Using configuration from ~/decentraland/explorer/packages/decentraland-ecs/api-extractor.json
Error: Symbol not found for identifier: Readonly
It also outputs the same message when using verbose mode.
Any thoughts? I just know that TS 3.4 also add a lot new stuff regarding to readonly behaviour
If I invoke your API Extractor installation from the command line like this:
cd ts-utils\libraries\map
node ..\..\common\temp\node_modules\.registry.npmjs.org\@microsoft\api-extractor\7.2.1\node_modules\@microsoft\api-extractor\bin\api-extractor run --local
...then it works just fine. But if it gets invoked by gulp, then it fails.
The failure is that the compiler engine doesn't know how to interpret Map<T1, T2> in your code below. In technical jargon, typeChecker.getSymbolAtLocation(identifierNode) cannot find the symbol:
map/lib/entries.d.ts
/** * Returns a two dimensional array of the entries of a map. * @param map - the map to get the entries of * @returns an array of the entries of the map * @public */exportdeclarefunctionentries<T1,T2>(map: Map<T1,T2>): Array<[T1,T2]>;"
Ah I see why it doesn't happen from the command-line. When you build with Gulp, (by design) the rush-stack-compiler-3.2 task configures the typescriptCompilerFolder to point to this folder:
...whereas API Extractor 7.2.1 when invoked from the command line would use the folder from TypeScript 3.4.5 (which is the compiler engine that AE uses for its analysis).
(The idea behind typescriptCompilerFolder is to ask the 3.4.5 compiler engine to analyze your project using the lib folder from 3.2.4. This avoids certain compile errors that can result from language changes between compiler releases. For example, the new readonly keyword. Although the lib folder can be redirected, API Extractor cannot safely load a different actual compiler engine, because the engine API sometimes has breaking changes between compiler versions.)
Comparing the two compiler folders, I can see that lib.es2015.collection.d.ts changed from this in TypeScript 3.2.4:
We expect the 3.4.5 compiler engine to be backwards compatible and understand these definitions that are missing readonly. I wonder why that isn't working. Perhaps the compiler internals somehow make assumptions about the Map class.
Actually I get this error even if I upgrade your project to use rush-stack-compiler-3.4 which uses 3.4.5. It must be something wrong with the ts.ParsedCommandLine constructed by _updateCommandLineForTypescriptPackage().
We need to add "lib.es2015.d.ts" (and probably other similar files) to the OTHER_BUILTIN_LIBRARIES list. That will avoid incorrectly bringing in lib.d.ts
We need to figure out why lib.es2015.d.ts is not bringing in any additional files.
Its implementation looks like this: lib/lib.es2015.d.ts
Thomas Clark (@tnc1997) that's good news! We should still fix this issue, however. Could I ask you to preserve your repro branch until we have solved the underlying issue?
Do you need to set noLib? Including a reference for one of the older built-in libs should result in the compiler encountering a /// <reference no-default-lib="true" /> comment and preventing it from loading the default lib for your options.
Another approach, since you are loading the compiler programmatically, is to provide a custom CompilerHost to ts.createProgram that customizes the behavior of the getDefaultLibLocation and getDefaultLibFileName methods.
I wasn't aware of the CompilerHost.getDefaultLibLocation API. It's probably the best solution, since it will eliminate the _updateCommandLineForTypescriptPackage() logic entirely.
It seems that wrapping CompilerHost will also help us to solve API Extractor issue #1310.
This works great. I confirmed that the ts-utils repro is solved for both rush-stack-compiler-3.2 and rush-stack-compiler-3.4. The resulting code is much simpler and more robust.
Activity
octogonz commentedon Jun 2, 2019
Internally API Extractor uses the 3.4.x engine, so this is probably a bug.
If you can provide a branch and some instructions for reproducing that error, I can debug it.
tnc1997 commentedon Jun 24, 2019
Hi Pete Gonzalez (@octogonz)
I'm unsure if my issue is related to this, however I'm receiving an error as follows:
Error: Symbol not found for identifier: MapI've pushed the code to a branch in my repository located here: tnc1997/ts-utils.
You should be able to reproduce this issue by:
rush update && rush build.Many Thanks
octogonz commentedon Jun 25, 2019
I'll take a look
octogonz commentedon Jun 26, 2019
Hrmmm... That is really strange.
If I invoke your API Extractor installation from the command line like this:
...then it works just fine. But if it gets invoked by gulp, then it fails.
octogonz commentedon Jun 26, 2019
The failure is that the compiler engine doesn't know how to interpret
Map<T1, T2>in your code below. In technical jargon,typeChecker.getSymbolAtLocation(identifierNode)cannot find the symbol:map/lib/entries.d.ts
Ah I see why it doesn't happen from the command-line. When you build with Gulp, (by design) the rush-stack-compiler-3.2 task configures the
typescriptCompilerFolderto point to this folder:...whereas API Extractor 7.2.1 when invoked from the command line would use the folder from TypeScript 3.4.5 (which is the compiler engine that AE uses for its analysis).
(The idea behind
typescriptCompilerFolderis to ask the 3.4.5 compiler engine to analyze your project using the lib folder from 3.2.4. This avoids certain compile errors that can result from language changes between compiler releases. For example, the newreadonlykeyword. Although the lib folder can be redirected, API Extractor cannot safely load a different actual compiler engine, because the engine API sometimes has breaking changes between compiler versions.)Comparing the two compiler folders, I can see that lib.es2015.collection.d.ts changed from this in TypeScript 3.2.4:
...to this in TypeScript 3.4.5 (adding
readonly):We expect the 3.4.5 compiler engine to be backwards compatible and understand these definitions that are missing
readonly. I wonder why that isn't working. Perhaps the compiler internals somehow make assumptions about theMapclass.octogonz commentedon Jun 26, 2019
Ron Buckton (@rbuckton) / Ryan Cavanaugh (@RyanCavanaugh) Do you have any idea why TypeScript 3.4.5 would fail to work with lib/lib.es2015.collection.d.ts from TypeScript 3.2.4?
By "fail to work with" I mean that
typeChecker.getSymbolAtLocation(identifierNode)returnsundefinedfor aMapnode.The
typescriptCompilerFoldersetting gets applied like this:https://github.com/microsoft/web-build-tools/blob/069a92e45016b8d879aa50d31f6d5d7f36f091e5/apps/api-extractor/src/api/CompilerState.ts#L137-L177
octogonz commentedon Jun 26, 2019
Actually I get this error even if I upgrade your project to use rush-stack-compiler-3.4 which uses 3.4.5. It must be something wrong with the
ts.ParsedCommandLineconstructed by_updateCommandLineForTypescriptPackage().octogonz commentedon Jun 26, 2019
When
typescriptCompilerFolderis omitted, theprogram.getSourceFiles()list is this:...whereas when it is specified, then we end up with this:
This is definitely a bug with
_updateCommandLineForTypescriptPackage().octogonz commentedon Jun 26, 2019
A couple problems:
"lib.es2015.d.ts"(and probably other similar files) to theOTHER_BUILTIN_LIBRARIESlist. That will avoid incorrectly bringing inlib.d.tslib.es2015.d.tsis not bringing in any additional files.Its implementation looks like this:
lib/lib.es2015.d.ts
It seems like maybe the
commandLine.options.noLib = trueoption is preventing these references from being followed. (?)octogonz commentedon Jun 26, 2019
Here we go: Looks like we got broken by TypeScript PR# 29022 ("Do not process library reference directives with noLib set").
tnc1997 commentedon Jun 26, 2019
Thank you very much for investigating the issue, it's pointed me in the direction of a workaround!
I can workaround the issue by changing the
ts-utils\libraries\map\tsconfig.jsonfile as follows:As you can see, I've removed the reference to
lib.es2015.d.tsand explicitly added the required libs.octogonz commentedon Jun 26, 2019
Thomas Clark (@tnc1997) that's good news! We should still fix this issue, however. Could I ask you to preserve your repro branch until we have solved the underlying issue?
octogonz commentedon Jun 26, 2019
In microsoft/TypeScript#29022 (comment) Ron Buckton (@rbuckton) said:
I wasn't aware of the
CompilerHost.getDefaultLibLocationAPI. It's probably the best solution, since it will eliminate the_updateCommandLineForTypescriptPackage()logic entirely.It seems that wrapping
CompilerHostwill also help us to solve API Extractor issue #1310.Replace CompilerState._updateCommandLineForTypescriptPackage() with a…
octogonz commentedon Jun 26, 2019
Here's a PR: #1341
This works great. I confirmed that the ts-utils repro is solved for both rush-stack-compiler-3.2 and rush-stack-compiler-3.4. The resulting code is much simpler and more robust.
Thanks Ron Buckton (@rbuckton) for suggesting this!
And thanks Thomas Clark (@tnc1997) for taking the time to report this and provide a repro!
octogonz commentedon Jun 26, 2019
I merged the PR. It will be published as API Extractor 7.2.2.
Replace CompilerState._updateCommandLineForTypescriptPackage() with a…