@@ -9,16 +9,11 @@ namespace ts {
99 /* @internal */ export let ioWriteTime = 0 ;
1010
1111 /** The version of the TypeScript compiler release */
12+ export const version = "1.9.0" ;
1213
1314 const emptyArray : any [ ] = [ ] ;
1415
15- const defaultLibrarySearchPaths = [
16- "types/" ,
17- "node_modules/" ,
18- "node_modules/@types/" ,
19- ] ;
20-
21- export const version = "1.9.0" ;
16+ const defaultTypeRoots = [ "node_modules/@types" ] ;
2217
2318 export function findConfigFile ( searchPath : string , fileExists : ( fileName : string ) => boolean ) : string {
2419 while ( true ) {
@@ -183,6 +178,11 @@ namespace ts {
183178
184179 const typeReferenceExtensions = [ ".d.ts" ] ;
185180
181+ function getEffectiveTypeRoots ( options : CompilerOptions , host : ModuleResolutionHost ) {
182+ return options . typeRoots ||
183+ defaultTypeRoots . map ( d => combinePaths ( options . configFilePath ? getDirectoryPath ( options . configFilePath ) : host . getCurrentDirectory ( ) , d ) ) ;
184+ }
185+
186186 /**
187187 * @param {string | undefined } containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
188188 * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -197,39 +197,36 @@ namespace ts {
197197 traceEnabled
198198 } ;
199199
200- // use typesRoot and fallback to directory that contains tsconfig or current directory if typesRoot is not set
201- const rootDir = options . typesRoot || ( options . configFilePath ? getDirectoryPath ( options . configFilePath ) : ( host . getCurrentDirectory && host . getCurrentDirectory ( ) ) ) ;
202-
200+ const typeRoots = getEffectiveTypeRoots ( options , host ) ;
203201 if ( traceEnabled ) {
204202 if ( containingFile === undefined ) {
205- if ( rootDir === undefined ) {
203+ if ( typeRoots === undefined ) {
206204 trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set , typeReferenceDirectiveName ) ;
207205 }
208206 else {
209- trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1 , typeReferenceDirectiveName , rootDir ) ;
207+ trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1 , typeReferenceDirectiveName , typeRoots ) ;
210208 }
211209 }
212210 else {
213- if ( rootDir === undefined ) {
211+ if ( typeRoots === undefined ) {
214212 trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set , typeReferenceDirectiveName , containingFile ) ;
215213 }
216214 else {
217- trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_1_root_directory_2 , typeReferenceDirectiveName , containingFile , rootDir ) ;
215+ trace ( host , Diagnostics . Resolving_type_reference_directive_0_containing_file_1_root_directory_2 , typeReferenceDirectiveName , containingFile , typeRoots ) ;
218216 }
219217 }
220218 }
221219
222220 const failedLookupLocations : string [ ] = [ ] ;
223221
224222 // Check primary library paths
225- if ( rootDir !== undefined ) {
226- const effectivePrimarySearchPaths = options . typesSearchPaths || defaultLibrarySearchPaths ;
227- for ( const searchPath of effectivePrimarySearchPaths ) {
228- const primaryPath = combinePaths ( rootDir , searchPath ) ;
229- if ( traceEnabled ) {
230- trace ( host , Diagnostics . Resolving_with_primary_search_path_0 , primaryPath ) ;
231- }
232- const candidate = combinePaths ( primaryPath , typeReferenceDirectiveName ) ;
223+ if ( typeRoots . length ) {
224+ if ( traceEnabled ) {
225+ trace ( host , Diagnostics . Resolving_with_primary_search_path_0 , typeRoots . join ( ", " ) ) ;
226+ }
227+ const primarySearchPaths = typeRoots ;
228+ for ( const typeRoot of primarySearchPaths ) {
229+ const candidate = combinePaths ( typeRoot , typeReferenceDirectiveName ) ;
233230 const candidateDirectory = getDirectoryPath ( candidate ) ;
234231 const resolvedFile = loadNodeModuleFromDirectory ( typeReferenceExtensions , candidate , failedLookupLocations ,
235232 ! directoryProbablyExists ( candidateDirectory , host ) , moduleResolutionState ) ;
@@ -256,9 +253,6 @@ namespace ts {
256253 if ( containingFile ) {
257254 initialLocationForSecondaryLookup = getDirectoryPath ( containingFile ) ;
258255 }
259- else {
260- initialLocationForSecondaryLookup = rootDir ;
261- }
262256
263257 if ( initialLocationForSecondaryLookup !== undefined ) {
264258 // check secondary locations
@@ -937,19 +931,6 @@ namespace ts {
937931 }
938932 }
939933
940- function getDefaultTypeDirectiveNames ( rootPath : string ) : string [ ] {
941- const localTypes = combinePaths ( rootPath , "types" ) ;
942- const npmTypes = combinePaths ( rootPath , "node_modules/@types" ) ;
943- let result : string [ ] = [ ] ;
944- if ( sys . directoryExists ( localTypes ) ) {
945- result = result . concat ( sys . getDirectories ( localTypes ) ) ;
946- }
947- if ( sys . directoryExists ( npmTypes ) ) {
948- result = result . concat ( sys . getDirectories ( npmTypes ) ) ;
949- }
950- return result ;
951- }
952-
953934 function getDefaultLibLocation ( ) : string {
954935 return getDirectoryPath ( normalizePath ( sys . getExecutingFilePath ( ) ) ) ;
955936 }
@@ -958,7 +939,6 @@ namespace ts {
958939 const realpath = sys . realpath && ( ( path : string ) => sys . realpath ( path ) ) ;
959940
960941 return {
961- getDefaultTypeDirectiveNames,
962942 getSourceFile,
963943 getDefaultLibLocation,
964944 getDefaultLibFileName : options => combinePaths ( getDefaultLibLocation ( ) , getDefaultLibFileName ( options ) ) ,
@@ -971,6 +951,7 @@ namespace ts {
971951 readFile : fileName => sys . readFile ( fileName ) ,
972952 trace : ( s : string ) => sys . write ( s + newLine ) ,
973953 directoryExists : directoryName => sys . directoryExists ( directoryName ) ,
954+ getDirectories : ( path : string ) => sys . getDirectories ( path ) ,
974955 realpath
975956 } ;
976957 }
@@ -1034,21 +1015,35 @@ namespace ts {
10341015 return resolutions ;
10351016 }
10361017
1037- export function getDefaultTypeDirectiveNames ( options : CompilerOptions , rootFiles : string [ ] , host : CompilerHost ) : string [ ] {
1018+ function getInferredTypesRoot ( options : CompilerOptions , rootFiles : string [ ] , host : CompilerHost ) {
1019+ return computeCommonSourceDirectoryOfFilenames ( rootFiles , host . getCurrentDirectory ( ) , f => host . getCanonicalFileName ( f ) ) ;
1020+ }
1021+
1022+ /**
1023+ * Given a set of options and a set of root files, returns the set of type directive names
1024+ * that should be included for this program automatically.
1025+ * This list could either come from the config file,
1026+ * or from enumerating the types root + initial secondary types lookup location.
1027+ * More type directives might appear in the program later as a result of loading actual source files;
1028+ * this list is only the set of defaults that are implicitly included.
1029+ */
1030+ export function getAutomaticTypeDirectiveNames ( options : CompilerOptions , rootFiles : string [ ] , host : CompilerHost ) : string [ ] {
10381031 // Use explicit type list from tsconfig.json
10391032 if ( options . types ) {
10401033 return options . types ;
10411034 }
10421035
1043- // or load all types from the automatic type import fields
1044- if ( host && host . getDefaultTypeDirectiveNames ) {
1045- const commonRoot = computeCommonSourceDirectoryOfFilenames ( rootFiles , host . getCurrentDirectory ( ) , f => host . getCanonicalFileName ( f ) ) ;
1046- if ( commonRoot ) {
1047- return host . getDefaultTypeDirectiveNames ( commonRoot ) ;
1036+ // Walk the primary type lookup locations
1037+ let result : string [ ] = [ ] ;
1038+ if ( host . directoryExists && host . getDirectories ) {
1039+ const typeRoots = getEffectiveTypeRoots ( options , host ) ;
1040+ for ( const root of typeRoots ) {
1041+ if ( host . directoryExists ( root ) ) {
1042+ result = result . concat ( host . getDirectories ( root ) ) ;
1043+ }
10481044 }
10491045 }
1050-
1051- return undefined ;
1046+ return result ;
10521047 }
10531048
10541049 export function createProgram ( rootNames : string [ ] , options : CompilerOptions , host ?: CompilerHost , oldProgram ?: Program ) : Program {
@@ -1100,11 +1095,13 @@ namespace ts {
11001095 if ( ! tryReuseStructureFromOldProgram ( ) ) {
11011096 forEach ( rootNames , name => processRootFile ( name , /*isDefaultLib*/ false ) ) ;
11021097
1103- // load type declarations specified via 'types' argument
1104- const typeReferences : string [ ] = getDefaultTypeDirectiveNames ( options , rootNames , host ) ;
1098+ // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
1099+ const typeReferences : string [ ] = getAutomaticTypeDirectiveNames ( options , rootNames , host ) ;
11051100
11061101 if ( typeReferences ) {
1107- const resolutions = resolveTypeReferenceDirectiveNamesWorker ( typeReferences , /*containingFile*/ undefined ) ;
1102+ const inferredRoot = getInferredTypesRoot ( options , rootNames , host ) ;
1103+ const containingFilename = combinePaths ( inferredRoot , "__inferred type names__.ts" ) ;
1104+ const resolutions = resolveTypeReferenceDirectiveNamesWorker ( typeReferences , containingFilename ) ;
11081105 for ( let i = 0 ; i < typeReferences . length ; i ++ ) {
11091106 processTypeReferenceDirective ( typeReferences [ i ] , resolutions [ i ] ) ;
11101107 }
@@ -1212,10 +1209,9 @@ namespace ts {
12121209 ( oldOptions . jsx !== options . jsx ) ||
12131210 ( oldOptions . allowJs !== options . allowJs ) ||
12141211 ( oldOptions . rootDir !== options . rootDir ) ||
1215- ( oldOptions . typesSearchPaths !== options . typesSearchPaths ) ||
12161212 ( oldOptions . configFilePath !== options . configFilePath ) ||
12171213 ( oldOptions . baseUrl !== options . baseUrl ) ||
1218- ( oldOptions . typesRoot !== options . typesRoot ) ||
1214+ ! arrayIsEqualTo ( oldOptions . typeRoots , oldOptions . typeRoots ) ||
12191215 ! arrayIsEqualTo ( oldOptions . rootDirs , options . rootDirs ) ||
12201216 ! mapIsEqualTo ( oldOptions . paths , options . paths ) ) {
12211217 return false ;
@@ -1970,7 +1966,7 @@ namespace ts {
19701966 }
19711967 }
19721968 else {
1973- fileProcessingDiagnostics . add ( createDiagnostic ( refFile , refPos , refEnd , Diagnostics . Cannot_find_name_0 , typeReferenceDirective ) ) ;
1969+ fileProcessingDiagnostics . add ( createDiagnostic ( refFile , refPos , refEnd , Diagnostics . Cannot_find_type_definition_file_for_0 , typeReferenceDirective ) ) ;
19741970 }
19751971
19761972 if ( saveResolution ) {
0 commit comments