@@ -314,9 +314,11 @@ namespace ts.Completions.PathCompletions {
314314
315315 function getCompletionEntriesFromTypings ( host : LanguageServiceHost , options : CompilerOptions , scriptPath : string , span : TextSpan , result : CompletionEntry [ ] = [ ] ) : CompletionEntry [ ] {
316316 // Check for typings specified in compiler options
317+ const seen = createMap < true > ( ) ;
317318 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 ) ;
320322 }
321323 }
322324 else if ( host . getDirectories ) {
@@ -328,32 +330,40 @@ namespace ts.Completions.PathCompletions {
328330
329331 if ( typeRoots ) {
330332 for ( const root of typeRoots ) {
331- getCompletionEntriesFromDirectories ( host , root , span , result ) ;
333+ getCompletionEntriesFromDirectories ( root ) ;
332334 }
333335 }
334- }
335336
336- if ( host . getDirectories ) {
337337 // Also get all @types typings installed in visible node_modules directories
338338 for ( const packageJson of findPackageJsons ( scriptPath , host ) ) {
339339 const typesDir = combinePaths ( getDirectoryPath ( packageJson ) , "node_modules/@types" ) ;
340- getCompletionEntriesFromDirectories ( host , typesDir , span , result ) ;
340+ getCompletionEntriesFromDirectories ( typesDir ) ;
341341 }
342342 }
343343
344344 return result ;
345- }
346345
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+ }
354357 }
355358 }
356359 }
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+ }
357367 }
358368
359369 function findPackageJsons ( directory : string , host : LanguageServiceHost ) : string [ ] {
0 commit comments