diff --git a/src/services/completions.ts b/src/services/completions.ts index 1c3288a3282..35f03697dd0 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1000,6 +1000,7 @@ namespace ts.Completions { let completionKind = CompletionKind.None; let isNewIdentifierLocation = false; let keywordFilters = KeywordCompletionFilters.None; + // This also gets mutated in nested-functions after the return let symbols: Symbol[] = []; const symbolToOriginInfoMap: SymbolOriginInfoMap = []; const symbolToSortTextMap: SymbolSortTextMap = []; @@ -1342,9 +1343,12 @@ namespace ts.Completions { } const symbolId = getSymbolId(symbol); - symbols.push(symbol); - symbolToOriginInfoMap[symbolId] = origin; - symbolToSortTextMap[symbolId] = SortText.AutoImportSuggestions; + const existingSymbol = findLast(symbols, symbol => symbol.id === symbolId); + if (!existingSymbol) { + symbols.push(symbol); + symbolToOriginInfoMap[symbolId] = origin; + symbolToSortTextMap[symbolId] = SortText.AutoImportSuggestions; + } }); } filterGlobalCompletion(symbols); diff --git a/tests/cases/fourslash/completionsRedeclareModuleAsGlobal.ts b/tests/cases/fourslash/completionsRedeclareModuleAsGlobal.ts new file mode 100644 index 00000000000..4a17a0830ac --- /dev/null +++ b/tests/cases/fourslash/completionsRedeclareModuleAsGlobal.ts @@ -0,0 +1,33 @@ +/// + +// @esModuleInterop: true, +// @target: esnext + +// @Filename: /myAssert.d.ts +////declare function assert(value:any, message?:string):void; +////export = assert; +////export as namespace assert; + +// @Filename: /ambient.d.ts +////import assert from './myAssert'; +//// +////type Assert = typeof assert; +//// +////declare global { +//// const assert: Assert; +////} + +// @Filename: /index.ts +/////// +////asser/**/; + +verify.completions({ + marker: "", + includes: [ + { + name: "assert", + sortText: completion.SortText.GlobalsOrKeywords + } + ], + preferences: { includeCompletionsForModuleExports: true, includeInsertTextCompletions: true } +});