@@ -801,7 +801,7 @@ namespace ts {
801801 }
802802 const resolvedFromFile = loadModuleFromFile ( extensions , candidate , failedLookupLocations , onlyRecordFailures , state ) ;
803803 if ( resolvedFromFile ) {
804- const nm = considerPackageJson ? parseNodeModuleFromPath ( resolvedFromFile . path ) : undefined ;
804+ const nm = considerPackageJson ? parseNodeModuleFromPath ( resolvedFromFile ) : undefined ;
805805 const packageId = nm && getPackageJsonInfo ( nm . packageDirectory , nm . subModuleName , failedLookupLocations , /*onlyRecordFailures*/ false , state ) . packageId ;
806806 return withPackageId ( packageId , resolvedFromFile ) ;
807807 }
@@ -826,12 +826,13 @@ namespace ts {
826826 *
827827 * packageDirectory is the directory of the package itself.
828828 * subModuleName is the path within the package.
829- * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. (Part before "/node_modules/" is ignored.)
830- * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }.
831- * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types /foo", subModuleName: "bar" }.
829+ * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "index.d.ts" }. (Part before "/node_modules/" is ignored.)
830+ * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }.
831+ * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types /foo", subModuleName: "bar/index.d.ts" }.
832+ * For `/node_modules/foo/bar/index.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }.
832833 */
833- function parseNodeModuleFromPath ( path : string ) : { packageDirectory : string , subModuleName : string } | undefined {
834- path = normalizePath ( path ) ;
834+ function parseNodeModuleFromPath ( resolved : PathAndExtension ) : { packageDirectory : string , subModuleName : string } | undefined {
835+ const path = normalizePath ( resolved . path ) ;
835836 const idx = path . lastIndexOf ( nodeModulesPathPart ) ;
836837 if ( idx === - 1 ) {
837838 return undefined ;
@@ -843,7 +844,7 @@ namespace ts {
843844 indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable ( path , indexAfterPackageName ) ;
844845 }
845846 const packageDirectory = path . slice ( 0 , indexAfterPackageName ) ;
846- const subModuleName = removeExtensionAndIndex ( path . slice ( indexAfterPackageName + 1 ) ) ;
847+ const subModuleName = removeExtension ( path . slice ( indexAfterPackageName + 1 ) , resolved . ext ) + Extension . Dts ;
847848 return { packageDirectory, subModuleName } ;
848849 }
849850
@@ -852,9 +853,17 @@ namespace ts {
852853 return nextSeparatorIndex === - 1 ? prevSeparatorIndex : nextSeparatorIndex ;
853854 }
854855
855- function removeExtensionAndIndex ( path : string ) : string {
856- const noExtension = removeFileExtension ( path ) ;
857- return noExtension === "index" ? "" : removeSuffix ( noExtension , "/index" ) ;
856+ function addExtensionAndIndex ( path : string ) : string {
857+ if ( path === "" ) {
858+ return "index.d.ts" ;
859+ }
860+ if ( endsWith ( path , ".d.ts" ) ) {
861+ return path ;
862+ }
863+ if ( endsWith ( path , "/index" ) ) {
864+ return path + ".d.ts" ;
865+ }
866+ return path + "/index.d.ts" ;
858867 }
859868
860869 /* @internal */
@@ -955,12 +964,31 @@ namespace ts {
955964 subModuleName : string ,
956965 failedLookupLocations : Push < string > ,
957966 onlyRecordFailures : boolean ,
958- { host , traceEnabled } : ModuleResolutionState ,
967+ state : ModuleResolutionState ,
959968 ) : { found : boolean , packageJsonContent : PackageJsonPathFields | undefined , packageId : PackageId | undefined } {
969+ const { host, traceEnabled } = state ;
960970 const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( nodeModuleDirectory , host ) ;
961971 const packageJsonPath = pathToPackageJson ( nodeModuleDirectory ) ;
962972 if ( directoryExists && host . fileExists ( packageJsonPath ) ) {
963973 const packageJsonContent = readJson ( packageJsonPath , host ) ;
974+ if ( subModuleName === "" ) { // looking up the root - need to handle types/typings/main redirects for subModuleName
975+ const path = tryReadPackageJsonFields ( /*readTypes*/ true , packageJsonContent , nodeModuleDirectory , state ) ;
976+ if ( typeof path === "string" ) {
977+ subModuleName = addExtensionAndIndex ( path . substring ( nodeModuleDirectory . length + 1 ) ) ;
978+ }
979+ else {
980+ const jsPath = tryReadPackageJsonFields ( /*readTypes*/ false , packageJsonContent , nodeModuleDirectory , state ) ;
981+ if ( typeof jsPath === "string" ) {
982+ subModuleName = removeExtension ( removeExtension ( jsPath . substring ( nodeModuleDirectory . length + 1 ) , Extension . Js ) , Extension . Jsx ) + Extension . Dts ;
983+ }
984+ else {
985+ subModuleName = "index.d.ts" ;
986+ }
987+ }
988+ }
989+ if ( ! endsWith ( subModuleName , Extension . Dts ) ) {
990+ subModuleName = addExtensionAndIndex ( subModuleName ) ;
991+ }
964992 const packageId : PackageId = typeof packageJsonContent . name === "string" && typeof packageJsonContent . version === "string"
965993 ? { name : packageJsonContent . name , subModuleName, version : packageJsonContent . version }
966994 : undefined ;
0 commit comments