44
55namespace ts {
66 /** The version of the TypeScript compiler release */
7+ export const version = "1.9.0" ;
78
89 const emptyArray : any [ ] = [ ] ;
910
10- const defaultLibrarySearchPaths = [
11- "types/" ,
12- "node_modules/" ,
13- "node_modules/@types/" ,
14- ] ;
15-
16- export const version = "1.9.0" ;
11+ const defaultTypeRoots = [ "node_modules/@types" ] ;
1712
1813 export function findConfigFile ( searchPath : string , fileExists : ( fileName : string ) => boolean ) : string {
1914 while ( true ) {
@@ -178,6 +173,11 @@ namespace ts {
178173
179174 const typeReferenceExtensions = [ ".d.ts" ] ;
180175
176+ function getEffectiveTypeRoots ( options : CompilerOptions , host : ModuleResolutionHost ) {
177+ return options . typeRoots ||
178+ defaultTypeRoots . map ( d => combinePaths ( options . configFilePath ? getDirectoryPath ( options . configFilePath ) : host . getCurrentDirectory ( ) , d ) ) ;
179+ }
180+
181181 /**
182182 * @param {string | undefined } containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
183183 * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -192,39 +192,36 @@ namespace ts {
192192 traceEnabled
193193 } ;
194194
195- // use typesRoot and fallback to directory that contains tsconfig or current directory if typesRoot is not set
196- const rootDir = options . typesRoot || ( options . configFilePath ? getDirectoryPath ( options . configFilePath ) : ( host . getCurrentDirectory && host . getCurrentDirectory ( ) ) ) ;
197-
195+ const typeRoots = getEffectiveTypeRoots ( options , host ) ;
198196 if ( traceEnabled ) {
199197 if ( containingFile === undefined ) {
200- if ( rootDir === undefined ) {
198+ if ( typeRoots === undefined ) {
201199 trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set , typeReferenceDirectiveName ) ;
202200 }
203201 else {
204- trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1 , typeReferenceDirectiveName , rootDir ) ;
202+ trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1 , typeReferenceDirectiveName , typeRoots ) ;
205203 }
206204 }
207205 else {
208- if ( rootDir === undefined ) {
206+ if ( typeRoots === undefined ) {
209207 trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set , typeReferenceDirectiveName , containingFile ) ;
210208 }
211209 else {
212- trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_1_root_directory_2 , typeReferenceDirectiveName , containingFile , rootDir ) ;
210+ trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_1_root_directory_2 , typeReferenceDirectiveName , containingFile , typeRoots ) ;
213211 }
214212 }
215213 }
216214
217215 const failedLookupLocations : string [ ] = [ ] ;
218216
219217 // Check primary library paths
220- if ( rootDir !== undefined ) {
221- const effectivePrimarySearchPaths = options . typesSearchPaths || defaultLibrarySearchPaths ;
222- for ( const searchPath of effectivePrimarySearchPaths ) {
223- const primaryPath = combinePaths ( rootDir , searchPath ) ;
224- if ( traceEnabled ) {
225- trace ( host , Diagnostics . Resolving_with_primary_search_path_0 , primaryPath ) ;
226- }
227- const candidate = combinePaths ( primaryPath , typeReferenceDirectiveName ) ;
218+ if ( typeRoots . length ) {
219+ if ( traceEnabled ) {
220+ trace ( host , Diagnostics . Resolving_with_primary_search_path_0 , typeRoots . join ( ", " ) ) ;
221+ }
222+ const primarySearchPaths = typeRoots ;
223+ for ( const typeRoot of primarySearchPaths ) {
224+ const candidate = combinePaths ( typeRoot , typeReferenceDirectiveName ) ;
228225 const candidateDirectory = getDirectoryPath ( candidate ) ;
229226 const resolvedFile = loadNodeModuleFromDirectory ( typeReferenceExtensions , candidate , failedLookupLocations ,
230227 ! directoryProbablyExists ( candidateDirectory , host ) , moduleResolutionState ) ;
@@ -251,9 +248,6 @@ namespace ts {
251248 if ( containingFile ) {
252249 initialLocationForSecondaryLookup = getDirectoryPath ( containingFile ) ;
253250 }
254- else {
255- initialLocationForSecondaryLookup = rootDir ;
256- }
257251
258252 if ( initialLocationForSecondaryLookup !== undefined ) {
259253 // check secondary locations
@@ -932,19 +926,6 @@ namespace ts {
932926 }
933927 }
934928
935- function getDefaultTypeDirectiveNames ( rootPath : string ) : string [ ] {
936- const localTypes = combinePaths ( rootPath , "types" ) ;
937- const npmTypes = combinePaths ( rootPath , "node_modules/@types" ) ;
938- let result : string [ ] = [ ] ;
939- if ( sys . directoryExists ( localTypes ) ) {
940- result = result . concat ( sys . getDirectories ( localTypes ) ) ;
941- }
942- if ( sys . directoryExists ( npmTypes ) ) {
943- result = result . concat ( sys . getDirectories ( npmTypes ) ) ;
944- }
945- return result ;
946- }
947-
948929 function getDefaultLibLocation ( ) : string {
949930 return getDirectoryPath ( normalizePath ( sys . getExecutingFilePath ( ) ) ) ;
950931 }
@@ -953,7 +934,6 @@ namespace ts {
953934 const realpath = sys . realpath && ( ( path : string ) => sys . realpath ( path ) ) ;
954935
955936 return {
956- getDefaultTypeDirectiveNames,
957937 getSourceFile,
958938 getDefaultLibLocation,
959939 getDefaultLibFileName : options => combinePaths ( getDefaultLibLocation ( ) , getDefaultLibFileName ( options ) ) ,
@@ -967,7 +947,8 @@ namespace ts {
967947 trace : ( s : string ) => sys . write ( s + newLine ) ,
968948 directoryExists : directoryName => sys . directoryExists ( directoryName ) ,
969949 realpath,
970- getEnvironmentVariable : name => getEnvironmentVariable ( name , /*host*/ undefined )
950+ getEnvironmentVariable : name => getEnvironmentVariable ( name , /*host*/ undefined ) ,
951+ getDirectories : ( path : string ) => sys . getDirectories ( path ) ,
971952 } ;
972953 }
973954
@@ -1030,21 +1011,35 @@ namespace ts {
10301011 return resolutions ;
10311012 }
10321013
1033- export function getDefaultTypeDirectiveNames ( options : CompilerOptions , rootFiles : string [ ] , host : CompilerHost ) : string [ ] {
1014+ function getInferredTypesRoot ( options : CompilerOptions , rootFiles : string [ ] , host : CompilerHost ) {
1015+ return computeCommonSourceDirectoryOfFilenames ( rootFiles , host . getCurrentDirectory ( ) , f => host . getCanonicalFileName ( f ) ) ;
1016+ }
1017+
1018+ /**
1019+ * Given a set of options and a set of root files, returns the set of type directive names
1020+ * that should be included for this program automatically.
1021+ * This list could either come from the config file,
1022+ * or from enumerating the types root + initial secondary types lookup location.
1023+ * More type directives might appear in the program later as a result of loading actual source files;
1024+ * this list is only the set of defaults that are implicitly included.
1025+ */
1026+ export function getAutomaticTypeDirectiveNames ( options : CompilerOptions , rootFiles : string [ ] , host : CompilerHost ) : string [ ] {
10341027 // Use explicit type list from tsconfig.json
10351028 if ( options . types ) {
10361029 return options . types ;
10371030 }
10381031
1039- // or load all types from the automatic type import fields
1040- if ( host && host . getDefaultTypeDirectiveNames ) {
1041- const commonRoot = computeCommonSourceDirectoryOfFilenames ( rootFiles , host . getCurrentDirectory ( ) , f => host . getCanonicalFileName ( f ) ) ;
1042- if ( commonRoot ) {
1043- return host . getDefaultTypeDirectiveNames ( commonRoot ) ;
1032+ // Walk the primary type lookup locations
1033+ let result : string [ ] = [ ] ;
1034+ if ( host . directoryExists && host . getDirectories ) {
1035+ const typeRoots = getEffectiveTypeRoots ( options , host ) ;
1036+ for ( const root of typeRoots ) {
1037+ if ( host . directoryExists ( root ) ) {
1038+ result = result . concat ( host . getDirectories ( root ) ) ;
1039+ }
10441040 }
10451041 }
1046-
1047- return undefined ;
1042+ return result ;
10481043 }
10491044
10501045 export function createProgram ( rootNames : string [ ] , options : CompilerOptions , host ?: CompilerHost , oldProgram ?: Program ) : Program {
@@ -1096,11 +1091,13 @@ namespace ts {
10961091 if ( ! tryReuseStructureFromOldProgram ( ) ) {
10971092 forEach ( rootNames , name => processRootFile ( name , /*isDefaultLib*/ false ) ) ;
10981093
1099- // load type declarations specified via 'types' argument
1100- const typeReferences : string [ ] = getDefaultTypeDirectiveNames ( options , rootNames , host ) ;
1094+ // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
1095+ const typeReferences : string [ ] = getAutomaticTypeDirectiveNames ( options , rootNames , host ) ;
11011096
11021097 if ( typeReferences ) {
1103- const resolutions = resolveTypeReferenceDirectiveNamesWorker ( typeReferences , /*containingFile*/ undefined ) ;
1098+ const inferredRoot = getInferredTypesRoot ( options , rootNames , host ) ;
1099+ const containingFilename = combinePaths ( inferredRoot , "__inferred type names__.ts" ) ;
1100+ const resolutions = resolveTypeReferenceDirectiveNamesWorker ( typeReferences , containingFilename ) ;
11041101 for ( let i = 0 ; i < typeReferences . length ; i ++ ) {
11051102 processTypeReferenceDirective ( typeReferences [ i ] , resolutions [ i ] ) ;
11061103 }
@@ -1208,10 +1205,9 @@ namespace ts {
12081205 ( oldOptions . jsx !== options . jsx ) ||
12091206 ( oldOptions . allowJs !== options . allowJs ) ||
12101207 ( oldOptions . rootDir !== options . rootDir ) ||
1211- ( oldOptions . typesSearchPaths !== options . typesSearchPaths ) ||
12121208 ( oldOptions . configFilePath !== options . configFilePath ) ||
12131209 ( oldOptions . baseUrl !== options . baseUrl ) ||
1214- ( oldOptions . typesRoot !== options . typesRoot ) ||
1210+ ! arrayIsEqualTo ( oldOptions . typeRoots , oldOptions . typeRoots ) ||
12151211 ! arrayIsEqualTo ( oldOptions . rootDirs , options . rootDirs ) ||
12161212 ! mapIsEqualTo ( oldOptions . paths , options . paths ) ) {
12171213 return false ;
@@ -1978,7 +1974,7 @@ namespace ts {
19781974 }
19791975 }
19801976 else {
1981- fileProcessingDiagnostics . add ( createDiagnostic ( refFile , refPos , refEnd , Diagnostics . Cannot_find_name_0 , typeReferenceDirective ) ) ;
1977+ fileProcessingDiagnostics . add ( createDiagnostic ( refFile , refPos , refEnd , Diagnostics . Cannot_find_type_definition_file_for_0 , typeReferenceDirective ) ) ;
19821978 }
19831979
19841980 if ( saveResolution ) {
0 commit comments