@@ -314,9 +314,11 @@ namespace ts.Completions.PathCompletions {
314
314
315
315
function getCompletionEntriesFromTypings ( host : LanguageServiceHost , options : CompilerOptions , scriptPath : string , span : TextSpan , result : CompletionEntry [ ] = [ ] ) : CompletionEntry [ ] {
316
316
// Check for typings specified in compiler options
317
+ const seen = createMap < true > ( ) ;
317
318
if ( options . types ) {
318
- for ( const moduleName of options . types ) {
319
- result . push ( createCompletionEntryForModule ( moduleName , ScriptElementKind . externalModuleName , span ) ) ;
319
+ for ( const typesName of options . types ) {
320
+ const moduleName = getUnmangledNameForScopedPackage ( typesName ) ;
321
+ pushResult ( moduleName ) ;
320
322
}
321
323
}
322
324
else if ( host . getDirectories ) {
@@ -328,32 +330,40 @@ namespace ts.Completions.PathCompletions {
328
330
329
331
if ( typeRoots ) {
330
332
for ( const root of typeRoots ) {
331
- getCompletionEntriesFromDirectories ( host , root , span , result ) ;
333
+ getCompletionEntriesFromDirectories ( root ) ;
332
334
}
333
335
}
334
- }
335
336
336
- if ( host . getDirectories ) {
337
337
// Also get all @types typings installed in visible node_modules directories
338
338
for ( const packageJson of findPackageJsons ( scriptPath , host ) ) {
339
339
const typesDir = combinePaths ( getDirectoryPath ( packageJson ) , "node_modules/@types" ) ;
340
- getCompletionEntriesFromDirectories ( host , typesDir , span , result ) ;
340
+ getCompletionEntriesFromDirectories ( typesDir ) ;
341
341
}
342
342
}
343
343
344
344
return result ;
345
- }
346
345
347
- function getCompletionEntriesFromDirectories ( host : LanguageServiceHost , directory : string , span : TextSpan , result : Push < CompletionEntry > ) {
348
- if ( host . getDirectories && tryDirectoryExists ( host , directory ) ) {
349
- const directories = tryGetDirectories ( host , directory ) ;
350
- if ( directories ) {
351
- for ( let typeDirectory of directories ) {
352
- typeDirectory = normalizePath ( typeDirectory ) ;
353
- result . push ( createCompletionEntryForModule ( getBaseFileName ( typeDirectory ) , ScriptElementKind . externalModuleName , span ) ) ;
346
+ function getCompletionEntriesFromDirectories ( directory : string ) {
347
+ Debug . assert ( ! ! host . getDirectories ) ;
348
+ if ( tryDirectoryExists ( host , directory ) ) {
349
+ const directories = tryGetDirectories ( host , directory ) ;
350
+ if ( directories ) {
351
+ for ( let typeDirectory of directories ) {
352
+ typeDirectory = normalizePath ( typeDirectory ) ;
353
+ const directoryName = getBaseFileName ( typeDirectory ) ;
354
+ const moduleName = getUnmangledNameForScopedPackage ( directoryName ) ;
355
+ pushResult ( moduleName ) ;
356
+ }
354
357
}
355
358
}
356
359
}
360
+
361
+ function pushResult ( moduleName : string ) {
362
+ if ( ! seen . has ( moduleName ) ) {
363
+ result . push ( createCompletionEntryForModule ( moduleName , ScriptElementKind . externalModuleName , span ) ) ;
364
+ seen . set ( moduleName , true ) ;
365
+ }
366
+ }
357
367
}
358
368
359
369
function findPackageJsons ( directory : string , host : LanguageServiceHost ) : string [ ] {
0 commit comments