@@ -668,51 +668,62 @@ namespace ts {
668
668
* @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
669
669
* 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.
670
670
*/
671
- function loadModuleFromFile ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string {
672
- // First try to keep/add an extension: importing "./foo.ts" can be matched by a file "./foo.ts", and "./foo" by "./foo.d.ts"
673
- const resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker ( candidate , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
674
- if ( resolvedByAddingOrKeepingExtension ) {
675
- return resolvedByAddingOrKeepingExtension ;
671
+ function loadModuleFromFile ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string | undefined {
672
+ // If the candidate already has an extension load that or quit.
673
+ if ( hasTypeScriptFileExtension ( candidate ) ) {
674
+ // Don't allow `.ts` to appear at the end
675
+ if ( ! fileExtensionIs ( candidate , ".d.ts" ) ) {
676
+ return undefined ;
677
+ }
678
+ return tryFile ( candidate , failedLookupLocation , onlyRecordFailures , state ) ;
676
679
}
677
- // 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"
680
+
681
+ // Next, try adding an extension.
682
+ // 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".
683
+ const resolvedByAddingExtension = tryAddingExtensions ( candidate , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
684
+ if ( resolvedByAddingExtension ) {
685
+ return resolvedByAddingExtension ;
686
+ }
687
+
688
+ // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
689
+ // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
678
690
if ( hasJavaScriptFileExtension ( candidate ) ) {
679
691
const extensionless = removeFileExtension ( candidate ) ;
680
692
if ( state . traceEnabled ) {
681
693
const extension = candidate . substring ( extensionless . length ) ;
682
694
trace ( state . host , Diagnostics . File_name_0_has_a_1_extension_stripping_it , candidate , extension ) ;
683
695
}
684
- return loadModuleFromFileWorker ( extensionless , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
696
+ return tryAddingExtensions ( extensionless , extensions , failedLookupLocation , onlyRecordFailures , state ) ;
685
697
}
686
698
}
687
699
688
- function loadModuleFromFileWorker ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string {
700
+ /** Try to return an existing file that adds one of the `extensions` to `candidate`. */
701
+ function tryAddingExtensions ( candidate : string , extensions : string [ ] , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string | undefined {
689
702
if ( ! onlyRecordFailures ) {
690
703
// check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
691
704
const directory = getDirectoryPath ( candidate ) ;
692
705
if ( directory ) {
693
706
onlyRecordFailures = ! directoryProbablyExists ( directory , state . host ) ;
694
707
}
695
708
}
696
- return forEach ( extensions , tryLoad ) ;
709
+ return forEach ( extensions , ext =>
710
+ ! ( state . skipTsx && isJsxOrTsxExtension ( ext ) ) && tryFile ( candidate + ext , failedLookupLocation , onlyRecordFailures , state ) ) ;
711
+ }
697
712
698
- function tryLoad ( ext : string ) : string {
699
- if ( state . skipTsx && isJsxOrTsxExtension ( ext ) ) {
700
- return undefined ;
701
- }
702
- const fileName = fileExtensionIs ( candidate , ext ) ? candidate : candidate + ext ;
703
- if ( ! onlyRecordFailures && state . host . fileExists ( fileName ) ) {
704
- if ( state . traceEnabled ) {
705
- trace ( state . host , Diagnostics . File_0_exist_use_it_as_a_name_resolution_result , fileName ) ;
706
- }
707
- return fileName ;
713
+ /** Return the file if it exists. */
714
+ function tryFile ( fileName : string , failedLookupLocation : string [ ] , onlyRecordFailures : boolean , state : ModuleResolutionState ) : string | undefined {
715
+ if ( ! onlyRecordFailures && state . host . fileExists ( fileName ) ) {
716
+ if ( state . traceEnabled ) {
717
+ trace ( state . host , Diagnostics . File_0_exist_use_it_as_a_name_resolution_result , fileName ) ;
708
718
}
709
- else {
710
- if ( state . traceEnabled ) {
711
- trace ( state . host , Diagnostics . File_0_does_not_exist , fileName ) ;
712
- }
713
- failedLookupLocation . push ( fileName ) ;
714
- return undefined ;
719
+ return fileName ;
720
+ }
721
+ else {
722
+ if ( state . traceEnabled ) {
723
+ trace ( state . host , Diagnostics . File_0_does_not_exist , fileName ) ;
715
724
}
725
+ failedLookupLocation . push ( fileName ) ;
726
+ return undefined ;
716
727
}
717
728
}
718
729
0 commit comments