@@ -679,51 +679,62 @@ namespace ts {
679
679
* @param {boolean } onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
680
680
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
681
681
*/
682
- function loadModuleFromFile ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string {
683
- // First try to keep/add an extension: importing "./foo.ts" can be matched by a file "./foo.ts", and "./foo" by "./foo.d.ts"
684
- const resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker ( candidate , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
685
- if ( resolvedByAddingOrKeepingExtension ) {
686
- return resolvedByAddingOrKeepingExtension ;
682
+ function loadModuleFromFile ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string | undefined {
683
+ // If the candidate already has an extension load that or quit.
684
+ if ( hasTypeScriptFileExtension ( candidate ) ) {
685
+ // Don't allow `.ts` to appear at the end
686
+ if ( ! fileExtensionIs ( candidate , ".d.ts" ) ) {
687
+ return undefined ;
688
+ }
689
+ return tryFile ( candidate , failedLookupLocation , onlyRecordFailures , state ) ;
687
690
}
688
- // Then try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one, e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
691
+
692
+ // Next, try adding an extension.
693
+ // We don't allow an import of "foo.ts" to be matched by "foo.ts.ts", but we do allow "foo.js" to be matched by "foo.js.ts".
694
+ const resolvedByAddingExtension = tryAddingExtensions ( candidate , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
695
+ if ( resolvedByAddingExtension ) {
696
+ return resolvedByAddingExtension ;
697
+ }
698
+
699
+ // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
700
+ // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
689
701
if ( hasJavaScriptFileExtension ( candidate ) ) {
690
702
const extensionless = removeFileExtension ( candidate ) ;
691
703
if ( state . traceEnabled ) {
692
704
const extension = candidate . substring ( extensionless . length ) ;
693
705
trace ( state . host , Diagnostics . File_name_0_has_a_1_extension_stripping_it , candidate , extension ) ;
694
706
}
695
- return loadModuleFromFileWorker ( extensionless , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
707
+ return tryAddingExtensions ( extensionless , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
696
708
}
697
709
}
698
710
699
- function loadModuleFromFileWorker ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string {
711
+ /** Try to return an existing file that adds one of the `extensions` to `candidate`. */
712
+ function tryAddingExtensions ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string | undefined {
700
713
if ( ! onlyRecordFailures ) {
701
714
// check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
702
715
const directory = getDirectoryPath ( candidate ) ;
703
716
if ( directory ) {
704
717
onlyRecordFailures = ! directoryProbablyExists ( directory , state . host ) ;
705
718
}
706
719
}
707
- return forEach ( extensions , tryLoad ) ;
720
+ return forEach ( extensions , ext =>
721
+ ! ( state . skipTsx && isJsxOrTsxExtension ( ext ) ) && tryFile ( candidate + ext , failedLookupLocation , onlyRecordFailures , state ) ) ;
722
+ }
708
723
709
- function tryLoad ( ext : string ) : string {
710
- if ( state . skipTsx && isJsxOrTsxExtension ( ext ) ) {
711
- return undefined ;
712
- }
713
- const fileName = fileExtensionIs ( candidate , ext ) ? candidate : candidate + ext ;
714
- if ( ! onlyRecordFailures && state . host . fileExists ( fileName ) ) {
715
- if ( state . traceEnabled ) {
716
- trace ( state . host , Diagnostics . File_0_exist_use_it_as_a_name_resolution_result , fileName ) ;
717
- }
718
- return fileName ;
724
+ /** Return the file if it exists. */
725
+ function tryFile ( fileName : string , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string | undefined {
726
+ if ( ! onlyRecordFailures && state . host . fileExists ( fileName ) ) {
727
+ if ( state . traceEnabled ) {
728
+ trace ( state . host , Diagnostics . File_0_exist_use_it_as_a_name_resolution_result , fileName ) ;
719
729
}
720
- else {
721
- if ( state . traceEnabled ) {
722
- trace ( state . host , Diagnostics . File_0_does_not_exist , fileName ) ;
723
- }
724
- failedLookupLocation . push ( fileName ) ;
725
- return undefined ;
730
+ return fileName ;
731
+ }
732
+ else {
733
+ if ( state . traceEnabled ) {
734
+ trace ( state . host , Diagnostics . File_0_does_not_exist , fileName ) ;
726
735
}
736
+ failedLookupLocation . push ( fileName ) ;
737
+ return undefined ;
727
738
}
728
739
}
729
740
0 commit comments