@@ -119,49 +119,31 @@ namespace ts {
119119 }
120120
121121 function tryReadTypesSection ( packageJsonPath : string , baseDirectory : string , state : ModuleResolutionState ) : string {
122- let jsonContent : { typings ?: string , types ?: string , main ?: string } ;
123- try {
124- const jsonText = state . host . readFile ( packageJsonPath ) ;
125- jsonContent = jsonText ? < { typings ?: string , types ?: string , main ?: string } > JSON . parse ( jsonText ) : { } ;
126- }
127- catch ( e ) {
128- // gracefully handle if readFile fails or returns not JSON
129- jsonContent = { } ;
130- }
131-
132- let typesFile : string ;
133- let fieldName : string ;
134- // first try to read content of 'typings' section (backward compatibility)
135- if ( jsonContent . typings ) {
136- if ( typeof jsonContent . typings === "string" ) {
137- fieldName = "typings" ;
138- typesFile = jsonContent . typings ;
139- }
140- else {
141- if ( state . traceEnabled ) {
142- trace ( state . host , Diagnostics . Expected_type_of_0_field_in_package_json_to_be_string_got_1 , "typings" , typeof jsonContent . typings ) ;
122+ const jsonContent = readJson ( packageJsonPath , state . host ) ;
123+
124+ function tryReadFromField ( fieldName : string ) {
125+ if ( hasProperty ( jsonContent , fieldName ) ) {
126+ const typesFile = ( < any > jsonContent ) [ fieldName ] ;
127+ if ( typeof typesFile === "string" ) {
128+ const typesFilePath = normalizePath ( combinePaths ( baseDirectory , typesFile ) ) ;
129+ if ( state . traceEnabled ) {
130+ trace ( state . host , Diagnostics . package_json_has_0_field_1_that_references_2 , fieldName , typesFile , typesFilePath ) ;
131+ }
132+ return typesFilePath ;
143133 }
144- }
145- }
146- // then read 'types'
147- if ( ! typesFile && jsonContent . types ) {
148- if ( typeof jsonContent . types === "string" ) {
149- fieldName = "types" ;
150- typesFile = jsonContent . types ;
151- }
152- else {
153- if ( state . traceEnabled ) {
154- trace ( state . host , Diagnostics . Expected_type_of_0_field_in_package_json_to_be_string_got_1 , "types" , typeof jsonContent . types ) ;
134+ else {
135+ if ( state . traceEnabled ) {
136+ trace ( state . host , Diagnostics . Expected_type_of_0_field_in_package_json_to_be_string_got_1 , fieldName , typeof typesFile ) ;
137+ }
155138 }
156139 }
157140 }
158- if ( typesFile ) {
159- const typesFilePath = normalizePath ( combinePaths ( baseDirectory , typesFile ) ) ;
160- if ( state . traceEnabled ) {
161- trace ( state . host , Diagnostics . package_json_has_0_field_1_that_references_2 , fieldName , typesFile , typesFilePath ) ;
162- }
141+
142+ const typesFilePath = tryReadFromField ( "typings" ) || tryReadFromField ( "types" ) ;
143+ if ( typesFilePath ) {
163144 return typesFilePath ;
164145 }
146+
165147 // Use the main module for inferring types if no types package specified and the allowJs is set
166148 if ( state . compilerOptions . allowJs && jsonContent . main && typeof jsonContent . main === "string" ) {
167149 if ( state . traceEnabled ) {
@@ -173,6 +155,17 @@ namespace ts {
173155 return undefined ;
174156 }
175157
158+ function readJson ( path : string , host : ModuleResolutionHost ) : { typings ?: string , types ?: string , main ?: string } {
159+ try {
160+ const jsonText = host . readFile ( path ) ;
161+ return jsonText ? JSON . parse ( jsonText ) : { } ;
162+ }
163+ catch ( e ) {
164+ // gracefully handle if readFile fails or returns not JSON
165+ return { } ;
166+ }
167+ }
168+
176169 const typeReferenceExtensions = [ ".d.ts" ] ;
177170
178171 function getEffectiveTypeRoots ( options : CompilerOptions , host : ModuleResolutionHost ) {
@@ -717,7 +710,7 @@ namespace ts {
717710 }
718711
719712 function loadNodeModuleFromDirectory ( extensions : string [ ] , candidate : string , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string {
720- const packageJsonPath = combinePaths ( candidate , "package.json" ) ;
713+ const packageJsonPath = pathToPackageJson ( candidate ) ;
721714 const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( candidate , state . host ) ;
722715 if ( directoryExists && state . host . fileExists ( packageJsonPath ) ) {
723716 if ( state . traceEnabled ) {
@@ -747,6 +740,10 @@ namespace ts {
747740 return loadModuleFromFile ( combinePaths ( candidate , "index" ) , extensions , failedLookupLocation , ! directoryExists , state ) ;
748741 }
749742
743+ function pathToPackageJson ( directory : string ) : string {
744+ return combinePaths ( directory , "package.json" ) ;
745+ }
746+
750747 function loadModuleFromNodeModulesFolder ( moduleName : string , directory : string , failedLookupLocations : string [ ] , state : ModuleResolutionState ) : string {
751748 const nodeModulesFolder = combinePaths ( directory , "node_modules" ) ;
752749 const nodeModulesFolderExists = directoryProbablyExists ( nodeModulesFolder , state . host ) ;
@@ -1070,15 +1067,21 @@ namespace ts {
10701067 }
10711068
10721069 // Walk the primary type lookup locations
1073- let result : string [ ] = [ ] ;
1070+ const result : string [ ] = [ ] ;
10741071 if ( host . directoryExists && host . getDirectories ) {
10751072 const typeRoots = getEffectiveTypeRoots ( options , host ) ;
10761073 if ( typeRoots ) {
10771074 for ( const root of typeRoots ) {
10781075 if ( host . directoryExists ( root ) ) {
10791076 for ( const typeDirectivePath of host . getDirectories ( root ) ) {
1080- // Return just the type directive names
1081- result = result . concat ( getBaseFileName ( normalizePath ( typeDirectivePath ) ) ) ;
1077+ const normalized = normalizePath ( typeDirectivePath )
1078+ const packageJsonPath = pathToPackageJson ( combinePaths ( root , normalized ) ) ;
1079+ // tslint:disable-next-line:no-null-keyword
1080+ const isNotNeededPackage = host . fileExists ( packageJsonPath ) && readJson ( packageJsonPath , host ) . typings === null ;
1081+ if ( ! isNotNeededPackage ) {
1082+ // Return just the type directive names
1083+ result . push ( getBaseFileName ( normalized ) ) ;
1084+ }
10821085 }
10831086 }
10841087 }
0 commit comments