@@ -107,24 +107,10 @@ namespace ts.Completions.PathCompletions {
107107
108108 // const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); // TODO(rbuckton): should use resolvePaths
109109 const absolutePath = resolvePath ( scriptPath , fragment ) ;
110- let baseDirectory = hasTrailingDirectorySeparator ( absolutePath ) ? absolutePath : getDirectoryPath ( absolutePath ) ;
110+ const baseDirectory = hasTrailingDirectorySeparator ( absolutePath ) ? absolutePath : getDirectoryPath ( absolutePath ) ;
111111 const ignoreCase = ! ( host . useCaseSensitiveFileNames && host . useCaseSensitiveFileNames ( ) ) ;
112112
113113 if ( tryDirectoryExists ( host , baseDirectory ) ) {
114- // check for a version redirect
115- const packageJsonPath = findPackageJson ( baseDirectory , host ) ;
116- if ( packageJsonPath ) {
117- const packageJson = readJson ( packageJsonPath , host as { readFile : ( filename : string ) => string | undefined } ) ;
118- const typesVersions = ( packageJson as any ) . typesVersions ;
119- if ( typeof typesVersions === "object" ) {
120- const result = getPackageJsonTypesVersionsOverride ( typesVersions ) ;
121- const versionPath = result && result . directory ;
122- if ( versionPath ) {
123- baseDirectory = resolvePath ( baseDirectory , versionPath ) ;
124- }
125- }
126- }
127-
128114 // Enumerate the available files if possible
129115 const files = tryReadDirectory ( host , baseDirectory , extensions , /*exclude*/ undefined , /*include*/ [ "./*" ] ) ;
130116
@@ -165,11 +151,41 @@ namespace ts.Completions.PathCompletions {
165151 }
166152 }
167153 }
154+
155+ // check for a version redirect
156+ const packageJsonPath = findPackageJson ( baseDirectory , host ) ;
157+ if ( packageJsonPath ) {
158+ const packageJson = readJson ( packageJsonPath , host as { readFile : ( filename : string ) => string | undefined } ) ;
159+ const typesVersions = ( packageJson as any ) . typesVersions ;
160+ if ( typeof typesVersions === "object" ) {
161+ const versionResult = getPackageJsonTypesVersionsPaths ( typesVersions ) ;
162+ const versionPaths = versionResult && versionResult . paths ;
163+ const rest = absolutePath . slice ( ensureTrailingDirectorySeparator ( baseDirectory ) . length ) ;
164+ if ( versionPaths ) {
165+ addCompletionEntriesFromPaths ( result , rest , baseDirectory , extensions , versionPaths , host ) ;
166+ }
167+ }
168+ }
168169 }
169170
170171 return result ;
171172 }
172173
174+ function addCompletionEntriesFromPaths ( result : NameAndKind [ ] , fragment : string , baseDirectory : string , fileExtensions : ReadonlyArray < string > , paths : MapLike < string [ ] > , host : LanguageServiceHost ) {
175+ for ( const path in paths ) {
176+ if ( ! hasProperty ( paths , path ) ) continue ;
177+ const patterns = paths [ path ] ;
178+ if ( patterns ) {
179+ for ( const { name, kind } of getCompletionsForPathMapping ( path , patterns , fragment , baseDirectory , fileExtensions , host ) ) {
180+ // Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
181+ if ( ! result . some ( entry => entry . name === name ) ) {
182+ result . push ( nameAndKind ( name , kind ) ) ;
183+ }
184+ }
185+ }
186+ }
187+ }
188+
173189 /**
174190 * Check all of the declared modules and those in node modules. Possible sources of modules:
175191 * Modules that are found by the type checker
@@ -185,19 +201,10 @@ namespace ts.Completions.PathCompletions {
185201 const fileExtensions = getSupportedExtensionsForModuleResolution ( compilerOptions ) ;
186202 if ( baseUrl ) {
187203 const projectDir = compilerOptions . project || host . getCurrentDirectory ( ) ;
188- const absolute = isRootedDiskPath ( baseUrl ) ? baseUrl : combinePaths ( projectDir , baseUrl ) ;
189- getCompletionEntriesForDirectoryFragment ( fragment , normalizePath ( absolute ) , fileExtensions , /*includeExtensions*/ false , host , /*exclude*/ undefined , result ) ;
190-
191- for ( const path in paths ! ) {
192- const patterns = paths ! [ path ] ;
193- if ( paths ! . hasOwnProperty ( path ) && patterns ) {
194- for ( const { name, kind } of getCompletionsForPathMapping ( path , patterns , fragment , baseUrl , fileExtensions , host ) ) {
195- // Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
196- if ( ! result . some ( entry => entry . name === name ) ) {
197- result . push ( nameAndKind ( name , kind ) ) ;
198- }
199- }
200- }
204+ const absolute = normalizePath ( combinePaths ( projectDir , baseUrl ) ) ;
205+ getCompletionEntriesForDirectoryFragment ( fragment , absolute , fileExtensions , /*includeExtensions*/ false , host , /*exclude*/ undefined , result ) ;
206+ if ( paths ) {
207+ addCompletionEntriesFromPaths ( result , fragment , absolute , fileExtensions , paths , host ) ;
201208 }
202209 }
203210
0 commit comments