From 6c9b2d9de91bdae20186b609a9b293ca22afd6e4 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 23 Jan 2018 15:48:48 -0800 Subject: [PATCH 01/42] Check syntax kind in isDeclarationNameOrImportPropertyName Otherwise, keywords are accepted. Assert was ``` fail (e:\ts_gh\src\compiler\core.ts:2867) assert (e:\ts_gh\src\compiler\core.ts:2837) isExportSpecifierAlias (e:\ts_gh\src\services\findAllReferences.ts:931) getLocalSymbolForExportSpecifier (e:\ts_gh\src\services\findAllReferences.ts:926) skipPastExportOrImportSpecifierOrUnion (e:\ts_gh\src\services\findAllReferences.ts:411) getReferencedSymbolsForSymbol (e:\ts_gh\src\services\findAllReferences.ts:359) getReferencedSymbolsForNode (e:\ts_gh\src\services\findAllReferences.ts:271) getReferenceEntriesForNode (e:\ts_gh\src\services\findAllReferences.ts:91) getSemanticDocumentHighlights (e:\ts_gh\src\services\documentHighlights.ts:25) getDocumentHighlights (e:\ts_gh\src\services\documentHighlights.ts:13) getDocumentHighlights (e:\ts_gh\src\services\services.ts:1584) getOccurrencesAtPositionCore (e:\ts_gh\src\services\services.ts:1588) getOccurrencesAtPosition (e:\ts_gh\src\services\services.ts:1567) Session.getOccurrences (e:\ts_gh\src\server\session.ts:718) Session.handlers.ts.createMapFromTemplate._a.(anonymous function) (e:\ts_gh\src\server\session.ts:1999) (anonymous function) (e:\ts_gh\src\server\session.ts:2079) Session.executeWithRequestId (e:\ts_gh\src\server\session.ts:2069) Session.executeCommand (e:\ts_gh\src\server\session.ts:2079) Session.onMessage (e:\ts_gh\src\server\session.ts:2101) (anonymous function) (e:\ts_gh\src\server\server.ts:593) ``` --- src/compiler/checker.ts | 2 +- src/harness/fourslash.ts | 13 +++++++++++++ tests/cases/fourslash/documentHighlightInExport1.ts | 11 +++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/documentHighlightInExport1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 01b3a047d1d..c58b69252fc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26580,7 +26580,7 @@ namespace ts { switch (name.parent.kind) { case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - return true; + return isIdentifier(name); default: return isDeclarationName(name); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index bf5f46de248..79ddf0ace40 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2876,6 +2876,15 @@ Actual: ${stringify(fullActual)}`); } } + public verifyNoDocumentHighlights(startRange: Range) { + this.goToRangeStart(startRange); + const documentHighlights = this.getDocumentHighlightsAtCurrentPosition([this.activeFile.fileName]); + const numHighlights = ts.length(documentHighlights); + if (numHighlights > 0) { + this.raiseError(`verifyNoDocumentHighlights failed - unexpectedly got ${numHighlights} highlights`); + } + } + private verifyDocumentHighlights(expectedRanges: Range[], fileNames: string[] = [this.activeFile.fileName]) { const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNames) || []; @@ -4284,6 +4293,10 @@ namespace FourSlashInterface { this.state.verifyDocumentHighlightsOf(startRange, ranges); } + public noDocumentHighlights(startRange: FourSlash.Range) { + this.state.verifyNoDocumentHighlights(startRange); + } + public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) { this.state.verifyCompletionEntryDetails(entryName, text, documentation, kind, tags); } diff --git a/tests/cases/fourslash/documentHighlightInExport1.ts b/tests/cases/fourslash/documentHighlightInExport1.ts new file mode 100644 index 00000000000..16b5261c5e0 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightInExport1.ts @@ -0,0 +1,11 @@ +/// + +// @Filename: file1.ts +//// class [|C|] {} +//// [|export|] { [|C|] [|as|] [|D|] }; + +const [classRange, exportKeywordRange, propertyNameRange, asKeywordRange, nameRange] = test.ranges(); +verify.noDocumentHighlights(exportKeywordRange); +verify.documentHighlightsOf(propertyNameRange, [classRange, propertyNameRange, nameRange]); +verify.noDocumentHighlights(asKeywordRange); +verify.documentHighlightsOf(nameRange, [nameRange]); From 4af47f188772591ecd996eb18a853c2cf1cd83f2 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Thu, 25 Jan 2018 14:06:11 -0800 Subject: [PATCH 02/42] Added NoEmit=true when jsconfig is present --- src/compiler/commandLineParser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index eb9f1e3cf34..bea29d3fc1c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1795,7 +1795,7 @@ namespace ts { function getDefaultCompilerOptions(configFileName?: string) { const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" - ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true } + ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, noEmit: true } : {}; return options; } From 25b1d9d6a5c1a0d5cc094dadc9c44514bf26b28d Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Thu, 25 Jan 2018 14:48:44 -0800 Subject: [PATCH 03/42] Updated tests --- src/harness/unittests/convertCompilerOptionsFromJson.ts | 8 ++++++-- src/harness/unittests/telemetry.ts | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 0bad2ba1e3a..6a88f2ba67e 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -457,6 +457,7 @@ namespace ts { maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, + noEmit: true, module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -486,6 +487,7 @@ namespace ts { maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, + noEmit: true, module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -510,7 +512,8 @@ namespace ts { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, - skipLibCheck: true + skipLibCheck: true, + noEmit: true }, errors: [{ file: undefined, @@ -532,7 +535,8 @@ namespace ts { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, - skipLibCheck: true + skipLibCheck: true, + noEmit: true }, errors: [] } diff --git a/src/harness/unittests/telemetry.ts b/src/harness/unittests/telemetry.ts index 9bb2db73801..5cea42efcf5 100644 --- a/src/harness/unittests/telemetry.ts +++ b/src/harness/unittests/telemetry.ts @@ -185,6 +185,7 @@ namespace ts.projectSystem { allowSyntheticDefaultImports: true, maxNodeModuleJsDepth: 2, skipLibCheck: true, + noEmit: true }; it("sends telemetry for typeAcquisition settings", () => { From 8ec36e988d79fde4ec12d85a4bfe7f93001c4205 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 23 Jan 2018 17:18:47 -0800 Subject: [PATCH 04/42] Add asserts upstream from #20809 --- src/compiler/utilities.ts | 14 +++++++++++++- src/services/refactors/extractSymbol.ts | 9 +++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f4ddf1d8319..b6700d21a70 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -681,10 +681,22 @@ namespace ts { return getSpanOfTokenAtPosition(sourceFile, node.pos); } - const pos = nodeIsMissing(errorNode) + const isMissing = nodeIsMissing(errorNode); + const pos = isMissing ? errorNode.pos : skipTrivia(sourceFile.text, errorNode.pos); + // These asserts should all be satisfied for a properly constructed `errorNode`. + // Upstream from https://github.com/Microsoft/TypeScript/issues/20809. + if (isMissing) { + Debug.assert(pos === errorNode.pos); + Debug.assert(pos === errorNode.end); + } + else { + Debug.assert(pos >= errorNode.pos); + Debug.assert(pos <= errorNode.end); + } + return createTextSpanFromBounds(pos, errorNode.end); } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index e3a2763b783..9b397584fed 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -335,6 +335,15 @@ namespace ts.refactor.extractSymbol { Continue = 1 << 1, Return = 1 << 2 } + + // This assert is upstream from https://github.com/Microsoft/TypeScript/issues/20809. + // We believe it's true because the node is from the (unmodified) tree. + Debug.assert(nodeToCheck.pos <= nodeToCheck.end); + + // This assert is upstream from https://github.com/Microsoft/TypeScript/issues/20809. + // For understanding how skipTrivia functioned: + Debug.assert(!positionIsSynthesized(nodeToCheck.pos)); + if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) { return [createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)]; } From 9bc0d33512675f5f45d1ac31d024f28c0c37ddbf Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 26 Jan 2018 11:12:34 -0800 Subject: [PATCH 05/42] Move bug URLs into assert messages --- src/compiler/utilities.ts | 9 ++++----- src/services/refactors/extractSymbol.ts | 6 ++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b6700d21a70..f2874b6b665 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -687,14 +687,13 @@ namespace ts { : skipTrivia(sourceFile.text, errorNode.pos); // These asserts should all be satisfied for a properly constructed `errorNode`. - // Upstream from https://github.com/Microsoft/TypeScript/issues/20809. if (isMissing) { - Debug.assert(pos === errorNode.pos); - Debug.assert(pos === errorNode.end); + Debug.assert(pos === errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809"); + Debug.assert(pos === errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809"); } else { - Debug.assert(pos >= errorNode.pos); - Debug.assert(pos <= errorNode.end); + Debug.assert(pos >= errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809"); + Debug.assert(pos <= errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809"); } return createTextSpanFromBounds(pos, errorNode.end); diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 9b397584fed..74a944077ec 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -336,13 +336,11 @@ namespace ts.refactor.extractSymbol { Return = 1 << 2 } - // This assert is upstream from https://github.com/Microsoft/TypeScript/issues/20809. // We believe it's true because the node is from the (unmodified) tree. - Debug.assert(nodeToCheck.pos <= nodeToCheck.end); + Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809"); - // This assert is upstream from https://github.com/Microsoft/TypeScript/issues/20809. // For understanding how skipTrivia functioned: - Debug.assert(!positionIsSynthesized(nodeToCheck.pos)); + Debug.assert(!positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809"); if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) { return [createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)]; From 873838360676d81ae0a463adf43190be17a0a912 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 30 Jan 2018 17:10:23 +0000 Subject: [PATCH 06/42] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 11 ++++++++++- .../diagnosticMessages.generated.json.lcl | 13 +++++++++++-- .../diagnosticMessages.generated.json.lcl | 11 ++++++++++- .../diagnosticMessages.generated.json.lcl | 13 +++++++++++-- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index c7e02a6c2cc..9a2e8e443e1 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -14,7 +14,7 @@ - + @@ -5103,6 +5103,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 517b05df202..acf7b098177 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -19,7 +19,7 @@ - + @@ -5112,6 +5112,15 @@ + + + + + + + + + @@ -8656,7 +8665,7 @@ - + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 1a892b757cb..a0888bc8397 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -14,7 +14,7 @@ - + @@ -5103,6 +5103,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index b534bf56365..9e337e473dc 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -14,7 +14,7 @@ - + @@ -5103,6 +5103,15 @@ + + + + + + + + + @@ -8647,7 +8656,7 @@ - + From cd12c8b63ba9b23e78b36177f22877b208f39aad Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 30 Jan 2018 10:22:29 -0800 Subject: [PATCH 07/42] Added datatables library to safelist --- src/harness/unittests/tsserverProjectSystem.ts | 17 +++++++++++++++-- src/server/editorServices.ts | 5 +++++ src/server/typesMap.json | 4 ++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index fee21fcdb2d..6834a598512 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1541,14 +1541,27 @@ namespace ts.projectSystem { path: "/scripts/Office/1/powerpoint.js", content: "unspecified" }; - const files = [file1, minFile, kendoFile1, kendoFile2, kendoFile3, officeFile1, officeFile2]; + const datatablesFile1 = { + path: "/js/jquery.datatables.js", + content: "unspecified" + }; + const datatablesFile2 = { + path: "/js/datatables.js", + content: "unspecified" + }; + const datatablesFile3 = { + path: "/js/datatables.all.min.js", + content: "unspecified" + }; + + const files = [file1, minFile, kendoFile1, kendoFile2, kendoFile3, officeFile1, officeFile2, datatablesFile1, datatablesFile2, datatablesFile3]; const host = createServerHost(files); const projectService = createProjectService(host); try { projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles(files.map(f => f.path)) }); const proj = projectService.externalProjects[0]; assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); - assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office"]); + assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office", "datatables.net"]); } finally { projectService.resetSafeList(); } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 5d71ff4c2d3..6bdbb68e704 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -158,6 +158,11 @@ namespace ts.server { "References": { match: /^(.*\/_references\.js)$/i, exclude: [["^", 1, "$"]] + }, + "Datatables.net": { + // e.g. /wwwroot/lib/datatables.all.min.js + match: /(jquery\.)*dataTables(\.all)*(\.min)*\.js$/i, + types: ["datatables.net"] } }; diff --git a/src/server/typesMap.json b/src/server/typesMap.json index 93e9c2502f8..06b907be513 100644 --- a/src/server/typesMap.json +++ b/src/server/typesMap.json @@ -22,6 +22,10 @@ "References": { "match": "^(.*\\/_references\\.js)$", "exclude": [["^", 1, "$"]] + }, + "Datatables.net": { + "match": "(jquery\\.)*dataTables(\\.all)*(\\.min)*\\.js$", + "types": ["datatables.net"] } }, "simpleMap": { From 8a561e72a89bfe972f1ab5d1a201f6d91336e88c Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 30 Jan 2018 10:46:17 -0800 Subject: [PATCH 08/42] Improved datatables regex --- src/server/editorServices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 6bdbb68e704..2337cc1d2db 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -161,7 +161,7 @@ namespace ts.server { }, "Datatables.net": { // e.g. /wwwroot/lib/datatables.all.min.js - match: /(jquery\.)*dataTables(\.all)*(\.min)*\.js$/i, + match: /(jquery\.)?dataTables(\.all)?(\.min)?\.js$/i, types: ["datatables.net"] } }; From cd994964e3edd9506c796de9ee951a3a49654d6a Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 30 Jan 2018 10:48:56 -0800 Subject: [PATCH 09/42] Improved datatables regex --- src/server/typesMap.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/typesMap.json b/src/server/typesMap.json index 06b907be513..c632ea1135c 100644 --- a/src/server/typesMap.json +++ b/src/server/typesMap.json @@ -24,7 +24,7 @@ "exclude": [["^", 1, "$"]] }, "Datatables.net": { - "match": "(jquery\\.)*dataTables(\\.all)*(\\.min)*\\.js$", + "match": "(jquery\\.)?dataTables(\\.all)?(\\.min)?\\.js$", "types": ["datatables.net"] } }, From b0ea899d1321a345cdead12f0290c56f2ec6e531 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 30 Jan 2018 11:09:48 -0800 Subject: [PATCH 10/42] Use the full local file path as the id for a submodule (#21471) * Use the full file path as the id for a submodule * Informal code review feedback --- src/compiler/moduleNameResolver.ts | 50 +++++++++++++++---- ...age_relativeImportWithinPackage.trace.json | 9 ++-- ...ativeImportWithinPackage_scoped.trace.json | 9 ++-- .../reference/library-reference-10.trace.json | 2 + .../reference/library-reference-11.trace.json | 1 + .../reference/library-reference-12.trace.json | 2 + .../reference/library-reference-2.trace.json | 4 ++ ...duleLocalImportNotIncorrectlyRedirected.js | 23 +++++++++ ...ocalImportNotIncorrectlyRedirected.symbols | 20 ++++++++ ...eLocalImportNotIncorrectlyRedirected.types | 20 ++++++++ ...lutionWithExtensions_unexpected.trace.json | 6 +++ ...utionWithExtensions_unexpected2.trace.json | 4 ++ ...on_packageJson_notAtPackageRoot.trace.json | 2 + ...AtPackageRoot_fakeScopedPackage.trace.json | 2 + ...ution_packageJson_scopedPackage.trace.json | 2 + ...on_packageJson_yesAtPackageRoot.trace.json | 4 +- ...AtPackageRoot_fakeScopedPackage.trace.json | 4 +- .../reference/packageJsonMain.trace.json | 18 +++++++ .../packageJsonMain_isNonRecursive.trace.json | 6 +++ .../reference/typingsLookup4.trace.json | 8 +++ ...duleLocalImportNotIncorrectlyRedirected.ts | 18 +++++++ 21 files changed, 193 insertions(+), 21 deletions(-) create mode 100644 tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.js create mode 100644 tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.symbols create mode 100644 tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.types create mode 100644 tests/cases/compiler/moduleLocalImportNotIncorrectlyRedirected.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index f72876bd5fc..50181bb98e4 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -801,7 +801,7 @@ namespace ts { } const resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile.path) : undefined; + const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined; const packageId = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, failedLookupLocations, /*onlyRecordFailures*/ false, state).packageId; return withPackageId(packageId, resolvedFromFile); } @@ -826,12 +826,13 @@ namespace ts { * * packageDirectory is the directory of the package itself. * subModuleName is the path within the package. - * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. (Part before "/node_modules/" is ignored.) - * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }. - * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar" }. + * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "index.d.ts" }. (Part before "/node_modules/" is ignored.) + * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }. + * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar/index.d.ts" }. + * For `/node_modules/foo/bar/index.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }. */ - function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { - path = normalizePath(path); + function parseNodeModuleFromPath(resolved: PathAndExtension): { packageDirectory: string, subModuleName: string } | undefined { + const path = normalizePath(resolved.path); const idx = path.lastIndexOf(nodeModulesPathPart); if (idx === -1) { return undefined; @@ -843,7 +844,7 @@ namespace ts { indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); } const packageDirectory = path.slice(0, indexAfterPackageName); - const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName + 1)); + const subModuleName = removeExtension(path.slice(indexAfterPackageName + 1), resolved.ext) + Extension.Dts; return { packageDirectory, subModuleName }; } @@ -852,9 +853,17 @@ namespace ts { return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex; } - function removeExtensionAndIndex(path: string): string { - const noExtension = removeFileExtension(path); - return noExtension === "index" ? "" : removeSuffix(noExtension, "/index"); + function addExtensionAndIndex(path: string): string { + if (path === "") { + return "index.d.ts"; + } + if (endsWith(path, ".d.ts")) { + return path; + } + if (endsWith(path, "/index")) { + return path + ".d.ts"; + } + return path + "/index.d.ts"; } /* @internal */ @@ -955,12 +964,31 @@ namespace ts { subModuleName: string, failedLookupLocations: Push, onlyRecordFailures: boolean, - { host, traceEnabled }: ModuleResolutionState, + state: ModuleResolutionState, ): { found: boolean, packageJsonContent: PackageJsonPathFields | undefined, packageId: PackageId | undefined } { + const { host, traceEnabled } = state; const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host); const packageJsonPath = pathToPackageJson(nodeModuleDirectory); if (directoryExists && host.fileExists(packageJsonPath)) { const packageJsonContent = readJson(packageJsonPath, host); + if (subModuleName === "") { // looking up the root - need to handle types/typings/main redirects for subModuleName + const path = tryReadPackageJsonFields(/*readTypes*/ true, packageJsonContent, nodeModuleDirectory, state); + if (typeof path === "string") { + subModuleName = addExtensionAndIndex(path.substring(nodeModuleDirectory.length + 1)); + } + else { + const jsPath = tryReadPackageJsonFields(/*readTypes*/ false, packageJsonContent, nodeModuleDirectory, state); + if (typeof jsPath === "string") { + subModuleName = removeExtension(removeExtension(jsPath.substring(nodeModuleDirectory.length + 1), Extension.Js), Extension.Jsx) + Extension.Dts; + } + else { + subModuleName = "index.d.ts"; + } + } + } + if (!endsWith(subModuleName, Extension.Dts)) { + subModuleName = addExtensionAndIndex(subModuleName); + } const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string" ? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version } : undefined; diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json index ae3917e931a..d592022e2e1 100644 --- a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json @@ -2,7 +2,7 @@ "======== Resolving module 'foo/use' from '/index.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/use' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/use@1.2.3'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/use/index.d.ts@1.2.3'.", "File '/node_modules/foo/use.ts' does not exist.", "File '/node_modules/foo/use.tsx' does not exist.", "File '/node_modules/foo/use.d.ts' exist - use it as a name resolution result.", @@ -26,12 +26,15 @@ "File '/node_modules/foo/index.ts' does not exist.", "File '/node_modules/foo/index.tsx' does not exist.", "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", - "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/index.d.ts@1.2.3'.", "======== Module name './index' was successfully resolved to '/node_modules/foo/index.d.ts'. ========", "======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' does not have a 'main' field.", + "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'. Package ID is 'foo/index.d.ts@1.2.3'.", "File '/node_modules/a/node_modules/foo.ts' does not exist.", "File '/node_modules/a/node_modules/foo.tsx' does not exist.", "File '/node_modules/a/node_modules/foo.d.ts' does not exist.", diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json index a753e3dfb9a..108873d70f9 100644 --- a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json @@ -2,7 +2,7 @@ "======== Resolving module '@foo/bar/use' from '/index.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module '@foo/bar/use' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/use@1.2.3'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/use/index.d.ts@1.2.3'.", "File '/node_modules/@foo/bar/use.ts' does not exist.", "File '/node_modules/@foo/bar/use.tsx' does not exist.", "File '/node_modules/@foo/bar/use.d.ts' exist - use it as a name resolution result.", @@ -26,12 +26,15 @@ "File '/node_modules/@foo/bar/index.ts' does not exist.", "File '/node_modules/@foo/bar/index.tsx' does not exist.", "File '/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", - "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/index.d.ts@1.2.3'.", "======== Module name './index' was successfully resolved to '/node_modules/@foo/bar/index.d.ts'. ========", "======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' does not have a 'main' field.", + "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/index.d.ts@1.2.3'.", "File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.", "File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.", "File '/node_modules/a/node_modules/@foo/bar.d.ts' does not exist.", diff --git a/tests/baselines/reference/library-reference-10.trace.json b/tests/baselines/reference/library-reference-10.trace.json index ada939d8129..ad34c0b1dc3 100644 --- a/tests/baselines/reference/library-reference-10.trace.json +++ b/tests/baselines/reference/library-reference-10.trace.json @@ -1,6 +1,7 @@ [ "======== Resolving type reference directive 'jquery', containing file '/foo/consumer.ts', root directory './types'. ========", "Resolving with primary search path './types'.", + "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", "Found 'package.json' at './types/jquery/package.json'.", "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", "File 'types/jquery/jquery.d.ts' exist - use it as a name resolution result.", @@ -8,6 +9,7 @@ "======== Type reference directive 'jquery' was successfully resolved to '/foo/types/jquery/jquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'jquery', containing file '/foo/__inferred type names__.ts', root directory './types'. ========", "Resolving with primary search path './types'.", + "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", "Found 'package.json' at './types/jquery/package.json'.", "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", "File 'types/jquery/jquery.d.ts' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/library-reference-11.trace.json b/tests/baselines/reference/library-reference-11.trace.json index ef99bb8912f..be260b6bc6e 100644 --- a/tests/baselines/reference/library-reference-11.trace.json +++ b/tests/baselines/reference/library-reference-11.trace.json @@ -3,6 +3,7 @@ "Root directory cannot be determined, skipping primary search paths.", "Looking up in 'node_modules' folder, initial location '/a/b'.", "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", + "'package.json' has 'typings' field 'jquery.d.ts' that references '/a/node_modules/jquery/jquery.d.ts'.", "Found 'package.json' at '/a/node_modules/jquery/package.json'.", "File '/a/node_modules/jquery.d.ts' does not exist.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/a/node_modules/jquery/jquery.d.ts'.", diff --git a/tests/baselines/reference/library-reference-12.trace.json b/tests/baselines/reference/library-reference-12.trace.json index 22b1232d30b..26361703708 100644 --- a/tests/baselines/reference/library-reference-12.trace.json +++ b/tests/baselines/reference/library-reference-12.trace.json @@ -3,6 +3,8 @@ "Root directory cannot be determined, skipping primary search paths.", "Looking up in 'node_modules' folder, initial location '/a/b'.", "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'dist/jquery.d.ts' that references '/a/node_modules/jquery/dist/jquery.d.ts'.", "Found 'package.json' at '/a/node_modules/jquery/package.json'.", "File '/a/node_modules/jquery.d.ts' does not exist.", "'package.json' does not have a 'typings' field.", diff --git a/tests/baselines/reference/library-reference-2.trace.json b/tests/baselines/reference/library-reference-2.trace.json index e708d11c464..6111a5e78cf 100644 --- a/tests/baselines/reference/library-reference-2.trace.json +++ b/tests/baselines/reference/library-reference-2.trace.json @@ -1,6 +1,8 @@ [ "======== Resolving type reference directive 'jquery', containing file '/consumer.ts', root directory '/types'. ========", "Resolving with primary search path '/types'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "Found 'package.json' at '/types/jquery/package.json'.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", @@ -9,6 +11,8 @@ "======== Type reference directive 'jquery' was successfully resolved to '/types/jquery/jquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'jquery', containing file 'test/__inferred type names__.ts', root directory '/types'. ========", "Resolving with primary search path '/types'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "Found 'package.json' at '/types/jquery/package.json'.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", diff --git a/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.js b/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.js new file mode 100644 index 00000000000..88a0f5a10f5 --- /dev/null +++ b/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/moduleLocalImportNotIncorrectlyRedirected.ts] //// + +//// [package.json] +{ +"name": "troublesome-lib", +"typings": "lib/index.d.ts", +"version": "0.0.1" +} +//// [index.d.ts] +import { Position } from './utilities/positioning'; +export interface ISpinButton {} +//// [positioning.d.ts] +export * from './positioning/index'; +//// [index.d.ts] +export declare enum Position { + top, +} +//// [index.ts] +import { ISpinButton } from "troublesome-lib"; + +//// [index.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.symbols b/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.symbols new file mode 100644 index 00000000000..aa2fb0375ed --- /dev/null +++ b/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/index.ts === +import { ISpinButton } from "troublesome-lib"; +>ISpinButton : Symbol(ISpinButton, Decl(index.ts, 0, 8)) + +=== tests/cases/compiler/node_modules/troublesome-lib/lib/index.d.ts === +import { Position } from './utilities/positioning'; +>Position : Symbol(Position, Decl(index.d.ts, 0, 8)) + +export interface ISpinButton {} +>ISpinButton : Symbol(ISpinButton, Decl(index.d.ts, 0, 51)) + +=== tests/cases/compiler/node_modules/troublesome-lib/lib/utilities/positioning.d.ts === +export * from './positioning/index'; +No type information for this code.=== tests/cases/compiler/node_modules/troublesome-lib/lib/utilities/positioning/index.d.ts === +export declare enum Position { +>Position : Symbol(Position, Decl(index.d.ts, 0, 0)) + + top, +>top : Symbol(Position.top, Decl(index.d.ts, 0, 30)) +} diff --git a/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.types b/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.types new file mode 100644 index 00000000000..f3186505cc8 --- /dev/null +++ b/tests/baselines/reference/moduleLocalImportNotIncorrectlyRedirected.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/index.ts === +import { ISpinButton } from "troublesome-lib"; +>ISpinButton : any + +=== tests/cases/compiler/node_modules/troublesome-lib/lib/index.d.ts === +import { Position } from './utilities/positioning'; +>Position : typeof Position + +export interface ISpinButton {} +>ISpinButton : ISpinButton + +=== tests/cases/compiler/node_modules/troublesome-lib/lib/utilities/positioning.d.ts === +export * from './positioning/index'; +No type information for this code.=== tests/cases/compiler/node_modules/troublesome-lib/lib/utilities/positioning/index.d.ts === +export declare enum Position { +>Position : Position + + top, +>top : Position +} diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json index b619535487b..5f32a4bf511 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json @@ -2,6 +2,9 @@ "======== Resolving module 'normalize.css' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'normalize.css' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", "Found 'package.json' at '/node_modules/normalize.css/package.json'.", "File '/node_modules/normalize.css.ts' does not exist.", "File '/node_modules/normalize.css.tsx' does not exist.", @@ -13,6 +16,9 @@ "File '/node_modules/normalize.css/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'normalize.css' from 'node_modules' folder, target file type 'JavaScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", "Found 'package.json' at '/node_modules/normalize.css/package.json'.", "File '/node_modules/normalize.css.js' does not exist.", "File '/node_modules/normalize.css.jsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json index 50e7fa685a6..bab6be18d39 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json @@ -2,6 +2,8 @@ "======== Resolving module 'foo' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.ts' does not exist.", "File '/node_modules/foo.tsx' does not exist.", @@ -24,6 +26,8 @@ "File '/node_modules/foo/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.js' does not exist.", "File '/node_modules/foo.jsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json index bf5f0b0bbef..3473f33c1f2 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json @@ -2,6 +2,8 @@ "======== Resolving module 'foo/bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/bar/types.d.ts'.", "Found 'package.json' at '/node_modules/foo/bar/package.json'.", "File '/node_modules/foo/bar.ts' does not exist.", "File '/node_modules/foo/bar.tsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json index 72d413d0b2c..07dc908b745 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json @@ -2,6 +2,8 @@ "======== Resolving module 'foo/@bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/@bar/types.d.ts'.", "Found 'package.json' at '/node_modules/foo/@bar/package.json'.", "File '/node_modules/foo/@bar.ts' does not exist.", "File '/node_modules/foo/@bar.tsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json index 69dcfca4eb6..77ea6a244c1 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json @@ -2,6 +2,8 @@ "======== Resolving module '@foo/bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/@foo/bar/types.d.ts'.", "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", "File '/node_modules/@foo/bar.ts' does not exist.", "File '/node_modules/@foo/bar.tsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json index e852d58f2b3..453f5c088a3 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar/index.d.ts@1.2.3'.", "File '/node_modules/foo/bar.ts' does not exist.", "File '/node_modules/foo/bar.tsx' does not exist.", "File '/node_modules/foo/bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar/index.d.ts@1.2.3'.", "File '/node_modules/foo/bar.js' does not exist.", "File '/node_modules/foo/bar.jsx' does not exist.", "File '/node_modules/foo/bar/index.js' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json index 19fe1f125bc..b84bac8993a 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar/index.d.ts@1.2.3'.", "File '/node_modules/foo/@bar.ts' does not exist.", "File '/node_modules/foo/@bar.tsx' does not exist.", "File '/node_modules/foo/@bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar/index.d.ts@1.2.3'.", "File '/node_modules/foo/@bar.js' does not exist.", "File '/node_modules/foo/@bar.jsx' does not exist.", "File '/node_modules/foo/@bar/index.js' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/packageJsonMain.trace.json b/tests/baselines/reference/packageJsonMain.trace.json index 842f70c3a02..6d39b9d4a7b 100644 --- a/tests/baselines/reference/packageJsonMain.trace.json +++ b/tests/baselines/reference/packageJsonMain.trace.json @@ -2,6 +2,9 @@ "======== Resolving module 'foo' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.ts' does not exist.", "File '/node_modules/foo.tsx' does not exist.", @@ -13,6 +16,9 @@ "File '/node_modules/foo/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.js' does not exist.", "File '/node_modules/foo.jsx' does not exist.", @@ -25,6 +31,9 @@ "======== Resolving module 'bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'bar' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'rab.js' that references '/node_modules/bar/rab.js'.", "Found 'package.json' at '/node_modules/bar/package.json'.", "File '/node_modules/bar.ts' does not exist.", "File '/node_modules/bar.tsx' does not exist.", @@ -36,6 +45,9 @@ "File '/node_modules/bar/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'bar' from 'node_modules' folder, target file type 'JavaScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'rab.js' that references '/node_modules/bar/rab.js'.", "Found 'package.json' at '/node_modules/bar/package.json'.", "File '/node_modules/bar.js' does not exist.", "File '/node_modules/bar.jsx' does not exist.", @@ -46,6 +58,9 @@ "======== Resolving module 'baz' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'baz' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'zab' that references '/node_modules/baz/zab'.", "Found 'package.json' at '/node_modules/baz/package.json'.", "File '/node_modules/baz.ts' does not exist.", "File '/node_modules/baz.tsx' does not exist.", @@ -57,6 +72,9 @@ "File '/node_modules/baz/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'baz' from 'node_modules' folder, target file type 'JavaScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'zab' that references '/node_modules/baz/zab'.", "Found 'package.json' at '/node_modules/baz/package.json'.", "File '/node_modules/baz.js' does not exist.", "File '/node_modules/baz.jsx' does not exist.", diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json index 763c86730ba..81f5be11a6d 100644 --- a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json @@ -2,6 +2,9 @@ "======== Resolving module 'foo' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.ts' does not exist.", "File '/node_modules/foo.tsx' does not exist.", @@ -13,6 +16,9 @@ "File '/node_modules/foo/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.js' does not exist.", "File '/node_modules/foo.jsx' does not exist.", diff --git a/tests/baselines/reference/typingsLookup4.trace.json b/tests/baselines/reference/typingsLookup4.trace.json index 133ea49c22a..6cd025d099a 100644 --- a/tests/baselines/reference/typingsLookup4.trace.json +++ b/tests/baselines/reference/typingsLookup4.trace.json @@ -5,6 +5,7 @@ "File '/node_modules/jquery.ts' does not exist.", "File '/node_modules/jquery.tsx' does not exist.", "File '/node_modules/jquery.d.ts' does not exist.", + "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", "Found 'package.json' at '/node_modules/@types/jquery/package.json'.", "File '/node_modules/@types/jquery.d.ts' does not exist.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", @@ -17,6 +18,7 @@ "File '/node_modules/kquery.ts' does not exist.", "File '/node_modules/kquery.tsx' does not exist.", "File '/node_modules/kquery.d.ts' does not exist.", + "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", "Found 'package.json' at '/node_modules/@types/kquery/package.json'.", "File '/node_modules/@types/kquery.d.ts' does not exist.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", @@ -33,6 +35,7 @@ "File '/node_modules/lquery.ts' does not exist.", "File '/node_modules/lquery.tsx' does not exist.", "File '/node_modules/lquery.d.ts' does not exist.", + "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", "Found 'package.json' at '/node_modules/@types/lquery/package.json'.", "File '/node_modules/@types/lquery.d.ts' does not exist.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", @@ -47,6 +50,7 @@ "File '/node_modules/mquery.ts' does not exist.", "File '/node_modules/mquery.tsx' does not exist.", "File '/node_modules/mquery.d.ts' does not exist.", + "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", "Found 'package.json' at '/node_modules/@types/mquery/package.json'.", "File '/node_modules/@types/mquery.d.ts' does not exist.", "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", @@ -61,6 +65,7 @@ "======== Module name 'mquery' was successfully resolved to '/node_modules/@types/mquery/mquery/index.tsx'. ========", "======== Resolving type reference directive 'jquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", + "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", "Found 'package.json' at '/node_modules/@types/jquery/package.json'.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", "File '/node_modules/@types/jquery/jquery.d.ts' exist - use it as a name resolution result.", @@ -68,6 +73,7 @@ "======== Type reference directive 'jquery' was successfully resolved to '/node_modules/@types/jquery/jquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'kquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", + "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", "Found 'package.json' at '/node_modules/@types/kquery/package.json'.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", "File '/node_modules/@types/kquery/kquery' does not exist.", @@ -79,6 +85,7 @@ "======== Type reference directive 'kquery' was successfully resolved to '/node_modules/@types/kquery/kquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'lquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", + "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", "Found 'package.json' at '/node_modules/@types/lquery/package.json'.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", "File '/node_modules/@types/lquery/lquery' does not exist.", @@ -88,6 +95,7 @@ "======== Type reference directive 'lquery' was successfully resolved to '/node_modules/@types/lquery/lquery.ts', primary: true. ========", "======== Resolving type reference directive 'mquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", + "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", "Found 'package.json' at '/node_modules/@types/mquery/package.json'.", "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", "File '/node_modules/@types/mquery/mquery' does not exist.", diff --git a/tests/cases/compiler/moduleLocalImportNotIncorrectlyRedirected.ts b/tests/cases/compiler/moduleLocalImportNotIncorrectlyRedirected.ts new file mode 100644 index 00000000000..89d967a32cd --- /dev/null +++ b/tests/cases/compiler/moduleLocalImportNotIncorrectlyRedirected.ts @@ -0,0 +1,18 @@ +// @noImplicitReferences: true +// @filename: node_modules/troublesome-lib/package.json +{ +"name": "troublesome-lib", +"typings": "lib/index.d.ts", +"version": "0.0.1" +} +// @filename: node_modules/troublesome-lib/lib/index.d.ts +import { Position } from './utilities/positioning'; +export interface ISpinButton {} +// @filename: node_modules/troublesome-lib/lib/utilities/positioning.d.ts +export * from './positioning/index'; +// @filename: node_modules/troublesome-lib/lib/utilities/positioning/index.d.ts +export declare enum Position { + top, +} +// @filename: index.ts +import { ISpinButton } from "troublesome-lib"; \ No newline at end of file From 3020f3d2e6deede0f599e330e2bc33ee3b2e7c2b Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 30 Jan 2018 13:25:39 -0800 Subject: [PATCH 11/42] Handle trivia in code fix forgotten-this Fixes #21433 --- .../codefixes/fixForgottenThisPropertyAccess.ts | 4 +++- .../codeFixForgottenThisPropertyAccess03.ts | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/codeFixForgottenThisPropertyAccess03.ts diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts index 19610da0b15..837487f1b8c 100644 --- a/src/services/codefixes/fixForgottenThisPropertyAccess.ts +++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts @@ -21,6 +21,8 @@ namespace ts.codefix { } function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Identifier): void { - changes.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token)); + // TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper + suppressLeadingAndTrailingTrivia(token); + changes.replaceRange(sourceFile, { pos: token.getStart(), end: token.end }, createPropertyAccess(createThis(), token)); } } \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixForgottenThisPropertyAccess03.ts b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess03.ts new file mode 100644 index 00000000000..2dd1c47b6f7 --- /dev/null +++ b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess03.ts @@ -0,0 +1,15 @@ +/// + +////class C { +//// foo: number; +//// constructor() {[| +//// /* a comment */foo = 10; +//// |]} +////} + +verify.codeFix({ + description: "Add 'this.' to unresolved variable", + newRangeContent: ` + /* a comment */this.foo = 10; + ` +}); From 6219be6144bf94310beef62dc98bb11ec20cfbc2 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 30 Jan 2018 14:16:44 -0800 Subject: [PATCH 12/42] Do no path canonicalization during config parsing (#20311) * Do no canonicalization during config parsing * Add test from issue * Apply code review feedback --- src/compiler/commandLineParser.ts | 47 +++++++++---------- .../unittests/tsserverProjectSystem.ts | 44 +++++++++++++++++ 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 9c30cb87a4d..b254bfc1031 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1425,9 +1425,9 @@ namespace ts { } function directoryOfCombinedPath(fileName: string, basePath: string) { - // Use the `identity` function to avoid canonicalizing the path, as it must remain noncanonical + // Use the `getNormalizedAbsolutePath` function to avoid canonicalizing the path, as it must remain noncanonical // until consistient casing errors are reported - return getDirectoryPath(toPath(fileName, basePath, identity)); + return getDirectoryPath(getNormalizedAbsolutePath(fileName, basePath)); } /** @@ -1452,8 +1452,7 @@ namespace ts { Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined)); const errors: Diagnostic[] = []; - const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames); - const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, getCanonicalFileName, resolutionStack, errors); + const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors); const { raw } = parsedConfig; const options = extend(existingOptions, parsedConfig.options || {}); options.configFilePath = configFileName; @@ -1547,7 +1546,10 @@ namespace ts { raw: any; options?: CompilerOptions; typeAcquisition?: TypeAcquisition; - extendedConfigPath?: Path; + /** + * Note that the case of the config path has not yet been normalized, as no files have been imported into the project yet + */ + extendedConfigPath?: string; } function isSuccessfulParsedTsconfig(value: ParsedTsconfig) { @@ -1564,12 +1566,11 @@ namespace ts { host: ParseConfigHost, basePath: string, configFileName: string, - getCanonicalFileName: GetCanonicalFileName, - resolutionStack: Path[], + resolutionStack: string[], errors: Push, ): ParsedTsconfig { basePath = normalizeSlashes(basePath); - const resolvedPath = toPath(configFileName || "", basePath, getCanonicalFileName); + const resolvedPath = getNormalizedAbsolutePath(configFileName || "", basePath); if (resolutionStack.indexOf(resolvedPath) >= 0) { errors.push(createCompilerDiagnostic(Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> "))); @@ -1577,14 +1578,13 @@ namespace ts { } const ownConfig = json ? - parseOwnConfigOfJson(json, host, basePath, getCanonicalFileName, configFileName, errors) : - parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, getCanonicalFileName, configFileName, errors); + parseOwnConfigOfJson(json, host, basePath, configFileName, errors) : + parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors); if (ownConfig.extendedConfigPath) { // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios. resolutionStack = resolutionStack.concat([resolvedPath]); - const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, getCanonicalFileName, - resolutionStack, errors); + const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors); if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) { const baseRaw = extendedConfig.raw; const raw = ownConfig.raw; @@ -1612,7 +1612,6 @@ namespace ts { json: any, host: ParseConfigHost, basePath: string, - getCanonicalFileName: GetCanonicalFileName, configFileName: string | undefined, errors: Push ): ParsedTsconfig { @@ -1625,7 +1624,7 @@ namespace ts { // It should be removed in future releases - use typeAcquisition instead. const typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName); json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors); - let extendedConfigPath: Path; + let extendedConfigPath: string; if (json.extends) { if (!isString(json.extends)) { @@ -1633,7 +1632,7 @@ namespace ts { } else { const newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath; - extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, getCanonicalFileName, errors, createCompilerDiagnostic); + extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, errors, createCompilerDiagnostic); } } return { raw: json, options, typeAcquisition, extendedConfigPath }; @@ -1643,13 +1642,12 @@ namespace ts { sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, - getCanonicalFileName: GetCanonicalFileName, configFileName: string | undefined, errors: Push ): ParsedTsconfig { const options = getDefaultCompilerOptions(configFileName); let typeAcquisition: TypeAcquisition, typingOptionstypeAcquisition: TypeAcquisition; - let extendedConfigPath: Path; + let extendedConfigPath: string; const optionsIterator: JsonConversionNotifier = { onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) { @@ -1670,7 +1668,6 @@ namespace ts { value, host, newBase, - getCanonicalFileName, errors, (message, arg0) => createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0) @@ -1712,7 +1709,6 @@ namespace ts { extendedConfig: string, host: ParseConfigHost, basePath: string, - getCanonicalFileName: GetCanonicalFileName, errors: Push, createDiagnostic: (message: DiagnosticMessage, arg1?: string) => Diagnostic) { extendedConfig = normalizeSlashes(extendedConfig); @@ -1721,9 +1717,9 @@ namespace ts { errors.push(createDiagnostic(Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig)); return undefined; } - let extendedConfigPath = toPath(extendedConfig, basePath, getCanonicalFileName); + let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath); if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, Extension.Json)) { - extendedConfigPath = `${extendedConfigPath}.json` as Path; + extendedConfigPath = `${extendedConfigPath}.json`; if (!host.fileExists(extendedConfigPath)) { errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig)); return undefined; @@ -1734,11 +1730,10 @@ namespace ts { function getExtendedConfig( sourceFile: JsonSourceFile, - extendedConfigPath: Path, + extendedConfigPath: string, host: ts.ParseConfigHost, basePath: string, - getCanonicalFileName: GetCanonicalFileName, - resolutionStack: Path[], + resolutionStack: string[], errors: Push, ): ParsedTsconfig | undefined { const extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path)); @@ -1752,14 +1747,14 @@ namespace ts { const extendedDirname = getDirectoryPath(extendedConfigPath); const extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, - getBaseFileName(extendedConfigPath), getCanonicalFileName, resolutionStack, errors); + getBaseFileName(extendedConfigPath), resolutionStack, errors); if (sourceFile) { sourceFile.extendedSourceFiles.push(...extendedResult.extendedSourceFiles); } if (isSuccessfulParsedTsconfig(extendedConfig)) { // Update the paths to reflect base path - const relativeDifference = convertToRelativePath(extendedDirname, basePath, getCanonicalFileName); + const relativeDifference = convertToRelativePath(extendedDirname, basePath, identity); const updatePath = (path: string) => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path); const mapPropertiesInRawIfNotUndefined = (propertyName: string) => { if (raw[propertyName]) { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index fee21fcdb2d..42199c895b1 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -6795,4 +6795,48 @@ namespace ts.projectSystem { } }); }); + + describe("tsserverProjectSystem forceConsistentCasingInFileNames", () => { + it("works when extends is specified with a case insensitive file system", () => { + const rootPath = "/Users/username/dev/project"; + const file1: FileOrFolder = { + path: `${rootPath}/index.ts`, + content: 'import {x} from "file2";', + }; + const file2: FileOrFolder = { + path: `${rootPath}/file2.js`, + content: "", + }; + const file2Dts: FileOrFolder = { + path: `${rootPath}/types/file2/index.d.ts`, + content: "export declare const x: string;", + }; + const tsconfigAll: FileOrFolder = { + path: `${rootPath}/tsconfig.all.json`, + content: JSON.stringify({ + compilerOptions: { + baseUrl: ".", + paths: { file2: ["./file2.js"] }, + typeRoots: ["./types"], + forceConsistentCasingInFileNames: true, + }, + }), + }; + const tsconfig: FileOrFolder = { + path: `${rootPath}/tsconfig.json`, + content: JSON.stringify({ extends: "./tsconfig.all.json" }), + }; + + const host = createServerHost([file1, file2, file2Dts, libFile, tsconfig, tsconfigAll], { useCaseSensitiveFileNames: false }); + const session = createSession(host); + + openFilesForSession([file1], session); + const projectService = session.getProjectService(); + + checkNumberOfProjects(projectService, { configuredProjects: 1 }); + + const diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); + assert.deepEqual(diagnostics, []); + }); + }); } From c161c22d896b8e5315f6127cebd8c4235d815cb4 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 30 Jan 2018 15:02:20 -0800 Subject: [PATCH 13/42] Avoid crashing when a source file is attempted to merge with another declaration (#21494) --- src/compiler/checker.ts | 2 + ...aceMergedWithImportAliasNoCrash.errors.txt | 25 +++++++++++ .../namespaceMergedWithImportAliasNoCrash.js | 32 ++++++++++++++ ...espaceMergedWithImportAliasNoCrash.symbols | 36 ++++++++++++++++ ...amespaceMergedWithImportAliasNoCrash.types | 42 +++++++++++++++++++ .../namespaceMergedWithImportAliasNoCrash.ts | 14 +++++++ 6 files changed, 151 insertions(+) create mode 100644 tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.errors.txt create mode 100644 tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.js create mode 100644 tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.symbols create mode 100644 tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.types create mode 100644 tests/cases/compiler/namespaceMergedWithImportAliasNoCrash.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8b579474382..16b2091733a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20273,6 +20273,8 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue; + case SyntaxKind.SourceFile: + return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue | DeclarationSpaces.ExportNamespace; // The below options all declare an Alias, which is allowed to merge with other values within the importing module case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.NamespaceImport: diff --git a/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.errors.txt b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.errors.txt new file mode 100644 index 00000000000..748bb587807 --- /dev/null +++ b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.errors.txt @@ -0,0 +1,25 @@ +tests/cases/compiler/file1.ts(5,1): error TS2708: Cannot use namespace 'Library' as a value. +tests/cases/compiler/file2.ts(1,8): error TS2440: Import declaration conflicts with local declaration of 'Lib'. +tests/cases/compiler/file2.ts(6,12): error TS2694: Namespace 'Lib' has no exported member 'Bar'. + + +==== tests/cases/compiler/file1.ts (1 errors) ==== + export namespace Library { + export type Bar = { a: number }; + } + var x: Library.Bar; // should work + Library.foo; // should be an error + ~~~~~~~ +!!! error TS2708: Cannot use namespace 'Library' as a value. +==== tests/cases/compiler/file2.ts (2 errors) ==== + import * as Lib from './file1'; + ~~~~~~~~ +!!! error TS2440: Import declaration conflicts with local declaration of 'Lib'. + namespace Lib { // should fail to merge + export const foo: string = ""; + } + Lib.foo; // should work + var x: Lib.Bar; // should be an error + ~~~ +!!! error TS2694: Namespace 'Lib' has no exported member 'Bar'. + export { Lib } \ No newline at end of file diff --git a/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.js b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.js new file mode 100644 index 00000000000..866aa225db9 --- /dev/null +++ b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/namespaceMergedWithImportAliasNoCrash.ts] //// + +//// [file1.ts] +export namespace Library { + export type Bar = { a: number }; +} +var x: Library.Bar; // should work +Library.foo; // should be an error +//// [file2.ts] +import * as Lib from './file1'; +namespace Lib { // should fail to merge + export const foo: string = ""; +} +Lib.foo; // should work +var x: Lib.Bar; // should be an error +export { Lib } + +//// [file1.js] +"use strict"; +exports.__esModule = true; +var x; // should work +Library.foo; // should be an error +//// [file2.js] +"use strict"; +exports.__esModule = true; +var Lib; +(function (Lib) { + Lib.foo = ""; +})(Lib || (Lib = {})); +exports.Lib = Lib; +Lib.foo; // should work +var x; // should be an error diff --git a/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.symbols b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.symbols new file mode 100644 index 00000000000..6e4fa919e2e --- /dev/null +++ b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/file1.ts === +export namespace Library { +>Library : Symbol(Library, Decl(file1.ts, 0, 0)) + + export type Bar = { a: number }; +>Bar : Symbol(Bar, Decl(file1.ts, 0, 26)) +>a : Symbol(a, Decl(file1.ts, 1, 23)) +} +var x: Library.Bar; // should work +>x : Symbol(x, Decl(file1.ts, 3, 3)) +>Library : Symbol(Library, Decl(file1.ts, 0, 0)) +>Bar : Symbol(Library.Bar, Decl(file1.ts, 0, 26)) + +Library.foo; // should be an error +=== tests/cases/compiler/file2.ts === +import * as Lib from './file1'; +>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31)) + +namespace Lib { // should fail to merge +>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31)) + + export const foo: string = ""; +>foo : Symbol(foo, Decl(file2.ts, 2, 16)) +} +Lib.foo; // should work +>Lib.foo : Symbol(Lib.foo, Decl(file2.ts, 2, 16)) +>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31)) +>foo : Symbol(Lib.foo, Decl(file2.ts, 2, 16)) + +var x: Lib.Bar; // should be an error +>x : Symbol(x, Decl(file2.ts, 5, 3)) +>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31)) + +export { Lib } +>Lib : Symbol(Lib, Decl(file2.ts, 6, 8)) + diff --git a/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.types b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.types new file mode 100644 index 00000000000..f0fe207b5a5 --- /dev/null +++ b/tests/baselines/reference/namespaceMergedWithImportAliasNoCrash.types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/file1.ts === +export namespace Library { +>Library : any + + export type Bar = { a: number }; +>Bar : Bar +>a : number +} +var x: Library.Bar; // should work +>x : Library.Bar +>Library : any +>Bar : Library.Bar + +Library.foo; // should be an error +>Library.foo : any +>Library : any +>foo : any + +=== tests/cases/compiler/file2.ts === +import * as Lib from './file1'; +>Lib : typeof Lib + +namespace Lib { // should fail to merge +>Lib : typeof Lib + + export const foo: string = ""; +>foo : string +>"" : "" +} +Lib.foo; // should work +>Lib.foo : string +>Lib : typeof Lib +>foo : string + +var x: Lib.Bar; // should be an error +>x : any +>Lib : any +>Bar : No type information available! + +export { Lib } +>Lib : typeof Lib + diff --git a/tests/cases/compiler/namespaceMergedWithImportAliasNoCrash.ts b/tests/cases/compiler/namespaceMergedWithImportAliasNoCrash.ts new file mode 100644 index 00000000000..8242c22dd7a --- /dev/null +++ b/tests/cases/compiler/namespaceMergedWithImportAliasNoCrash.ts @@ -0,0 +1,14 @@ +// @filename: file1.ts +export namespace Library { + export type Bar = { a: number }; +} +var x: Library.Bar; // should work +Library.foo; // should be an error +// @filename: file2.ts +import * as Lib from './file1'; +namespace Lib { // should fail to merge + export const foo: string = ""; +} +Lib.foo; // should work +var x: Lib.Bar; // should be an error +export { Lib } \ No newline at end of file From 4518e03e48a5401788d1ed09171af7cacd1119a4 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 30 Jan 2018 23:10:57 +0000 Subject: [PATCH 14/42] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 2 +- .../diagnosticMessages.generated.json.lcl | 13 +++++++++++-- .../diagnosticMessages.generated.json.lcl | 13 +++++++++++-- .../diagnosticMessages.generated.json.lcl | 13 +++++++++++-- .../diagnosticMessages.generated.json.lcl | 11 ++++++++++- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 9a2e8e443e1..f45c317dcdd 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -8656,7 +8656,7 @@ - + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3747e00c1f9..ffaf6621ac5 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -19,7 +19,7 @@ - + @@ -5112,6 +5112,15 @@ + + + + + + + + + @@ -8656,7 +8665,7 @@ - + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 4d8f2721a08..6251fa14008 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -14,7 +14,7 @@ - + @@ -5100,6 +5100,15 @@ + + + + + + + + + @@ -8638,7 +8647,7 @@ - + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index c5473f41421..9b7661ee541 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -7,7 +7,7 @@ - + @@ -5093,6 +5093,15 @@ + + + + + + + + + @@ -8631,7 +8640,7 @@ - + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 44a9f695fca..343994d2cab 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -7,7 +7,7 @@ - + @@ -5096,6 +5096,15 @@ + + + + + + + + + From e99fe781723bef575a0155e18f1b64d367eb3ee3 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 30 Jan 2018 15:22:34 -0800 Subject: [PATCH 15/42] Addressed PR comments --- src/server/editorServices.ts | 5 ----- src/server/typesMap.json | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 2337cc1d2db..5d71ff4c2d3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -158,11 +158,6 @@ namespace ts.server { "References": { match: /^(.*\/_references\.js)$/i, exclude: [["^", 1, "$"]] - }, - "Datatables.net": { - // e.g. /wwwroot/lib/datatables.all.min.js - match: /(jquery\.)?dataTables(\.all)?(\.min)?\.js$/i, - types: ["datatables.net"] } }; diff --git a/src/server/typesMap.json b/src/server/typesMap.json index c632ea1135c..7da4f57af70 100644 --- a/src/server/typesMap.json +++ b/src/server/typesMap.json @@ -24,7 +24,7 @@ "exclude": [["^", 1, "$"]] }, "Datatables.net": { - "match": "(jquery\\.)?dataTables(\\.all)?(\\.min)?\\.js$", + "match": "^.*\\/(jquery\\.)?dataTables(\\.all)?(\\.min)?\\.js$", "types": ["datatables.net"] } }, From 25f20da200a4050b90fbf5b0517055ab8376e007 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 30 Jan 2018 17:03:54 -0800 Subject: [PATCH 16/42] Added Ace and PDFKit to typesMap --- src/harness/unittests/tsserverProjectSystem.ts | 16 ++-------------- src/server/typesMap.json | 6 ++++++ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 6834a598512..49f063ee604 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1541,27 +1541,15 @@ namespace ts.projectSystem { path: "/scripts/Office/1/powerpoint.js", content: "unspecified" }; - const datatablesFile1 = { - path: "/js/jquery.datatables.js", - content: "unspecified" - }; - const datatablesFile2 = { - path: "/js/datatables.js", - content: "unspecified" - }; - const datatablesFile3 = { - path: "/js/datatables.all.min.js", - content: "unspecified" - }; - const files = [file1, minFile, kendoFile1, kendoFile2, kendoFile3, officeFile1, officeFile2, datatablesFile1, datatablesFile2, datatablesFile3]; + const files = [file1, minFile, kendoFile1, kendoFile2, kendoFile3, officeFile1, officeFile2]; const host = createServerHost(files); const projectService = createProjectService(host); try { projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles(files.map(f => f.path)) }); const proj = projectService.externalProjects[0]; assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); - assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office", "datatables.net"]); + assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office"]); } finally { projectService.resetSafeList(); } diff --git a/src/server/typesMap.json b/src/server/typesMap.json index 7da4f57af70..cfe7f6483c4 100644 --- a/src/server/typesMap.json +++ b/src/server/typesMap.json @@ -26,6 +26,11 @@ "Datatables.net": { "match": "^.*\\/(jquery\\.)?dataTables(\\.all)?(\\.min)?\\.js$", "types": ["datatables.net"] + }, + "Ace": { + "match": "^(.*)\\/ace.js", + "exclude": [["^", 1, "/.*"]], + "types": ["ace"] } }, "simpleMap": { @@ -356,6 +361,7 @@ "passport": "passport", "passport-local": "passport-local", "path": "pathjs", + "pdfkit":"pdfkit", "peer": "peerjs", "peg": "pegjs", "photoswipe": "photoswipe", From 559531cd8b034ea10a450d423e55af7a9abf2bef Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 30 Jan 2018 17:05:44 -0800 Subject: [PATCH 17/42] Minor fixes --- src/harness/unittests/tsserverProjectSystem.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 49f063ee604..fee21fcdb2d 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1541,7 +1541,6 @@ namespace ts.projectSystem { path: "/scripts/Office/1/powerpoint.js", content: "unspecified" }; - const files = [file1, minFile, kendoFile1, kendoFile2, kendoFile3, officeFile1, officeFile2]; const host = createServerHost(files); const projectService = createProjectService(host); From f1e25b3186ad9ee77d653ffd9d8a21631698585f Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 31 Jan 2018 05:10:17 +0000 Subject: [PATCH 18/42] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 11 ++++++++++- .../diagnosticMessages.generated.json.lcl | 13 +++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 080b2e11402..dc5a7d359d5 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -7,7 +7,7 @@ - + @@ -5093,6 +5093,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index bb0b07794a3..1bcd0308ab4 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -13,7 +13,7 @@ - + @@ -5102,6 +5102,15 @@ + + + + + + + + + @@ -8646,7 +8655,7 @@ - + From cd0000110d0c13ed3a38f022204421289f97dbc7 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 31 Jan 2018 11:12:09 -0800 Subject: [PATCH 19/42] Add FAR test --- tests/cases/fourslash/documentHighlightInExport1.ts | 1 - tests/cases/fourslash/findAllRefsInExport1.ts | 10 ++++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/findAllRefsInExport1.ts diff --git a/tests/cases/fourslash/documentHighlightInExport1.ts b/tests/cases/fourslash/documentHighlightInExport1.ts index 16b5261c5e0..bf5bc7cfa94 100644 --- a/tests/cases/fourslash/documentHighlightInExport1.ts +++ b/tests/cases/fourslash/documentHighlightInExport1.ts @@ -1,6 +1,5 @@ /// -// @Filename: file1.ts //// class [|C|] {} //// [|export|] { [|C|] [|as|] [|D|] }; diff --git a/tests/cases/fourslash/findAllRefsInExport1.ts b/tests/cases/fourslash/findAllRefsInExport1.ts new file mode 100644 index 00000000000..02ec901177f --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInExport1.ts @@ -0,0 +1,10 @@ +/// + +//// class C {} +//// /*1*/export { C /*2*/as D }; + +goTo.marker("1"); +verify.noReferences(); + +goTo.marker("2"); +verify.noReferences(); \ No newline at end of file From d0ab1642fe7327f486b41d97e6c6f81e082403e0 Mon Sep 17 00:00:00 2001 From: TravCav Date: Wed, 31 Jan 2018 15:59:17 -0500 Subject: [PATCH 20/42] Fix for Issue #21512 and code cleanup for Jakefile.js (#21513) * Code cleanup for Jakefile.js Jakefile.js was throwing lint warnings so I cleaned some of them up. * took out jshint flag removed /*jshint esversion: 6 */ --- Jakefile.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 87fca36a841..b986d81dacc 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -8,7 +8,6 @@ var child_process = require("child_process"); var fold = require("travis-fold"); var ts = require("./lib/typescript"); - // Variables var compilerDirectory = "src/compiler/"; var serverDirectory = "src/server/"; @@ -86,7 +85,7 @@ var servicesSources = filesFromConfig("./src/services/tsconfig.json"); var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json")); var typingsInstallerSources = filesFromConfig(path.join(serverDirectory, "typingsInstaller/tsconfig.json")); var watchGuardSources = filesFromConfig(path.join(serverDirectory, "watchGuard/tsconfig.json")); -var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json")) +var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json")); var languageServiceLibrarySources = filesFromConfig(path.join(serverDirectory, "tsconfig.library.json")); var typesMapOutputPath = path.join(builtLocalDirectory, 'typesMap.json'); @@ -332,7 +331,7 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts var startCompileTime = mark(); opts = opts || {}; var compilerPath = useBuiltCompiler ? builtLocalCompiler : LKGCompiler; - var options = "--noImplicitAny --noImplicitThis --alwaysStrict --noEmitOnError --types " + var options = "--noImplicitAny --noImplicitThis --alwaysStrict --noEmitOnError --types "; if (opts.types) { options += opts.types.join(","); } @@ -381,10 +380,10 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts } options += " --target es5"; if (opts.lib) { - options += " --lib " + opts.lib + options += " --lib " + opts.lib; } else { - options += " --lib es5" + options += " --lib es5"; } options += " --noUnusedLocals --noUnusedParameters"; @@ -526,7 +525,7 @@ file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts] complete(); }); ex.run(); -}, { async: true }) +}, { async: true }); // The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () { @@ -646,7 +645,7 @@ compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].conc // Stanalone/web definition file using global 'ts' namespace jake.cpR(standaloneDefinitionsFile, nodeDefinitionsFile, { silent: true }); var definitionFileContents = fs.readFileSync(nodeDefinitionsFile).toString(); - definitionFileContents = removeConstModifierFromEnumDeclarations(definitionFileContents) + definitionFileContents = removeConstModifierFromEnumDeclarations(definitionFileContents); fs.writeFileSync(standaloneDefinitionsFile, definitionFileContents); // Official node package definition file, pointed to by 'typings' in package.json @@ -1253,7 +1252,7 @@ task("build-rules-end", [], function () { var lintTargets = compilerSources .concat(harnessSources) // Other harness sources - .concat(["instrumenter.ts"].map(function (f) { return path.join(harnessDirectory, f) })) + .concat(["instrumenter.ts"].map(function (f) { return path.join(harnessDirectory, f); })) .concat(serverSources) .concat(tslintRulesFiles) .concat(servicesSources) @@ -1261,7 +1260,7 @@ var lintTargets = compilerSources .concat(cancellationTokenSources) .concat(["Gulpfile.ts"]) .concat([nodeServerInFile, perftscPath, "tests/perfsys.ts", webhostPath]) - .map(function (p) { return path.resolve(p) }); + .map(function (p) { return path.resolve(p); }); // keep only unique items lintTargets = Array.from(new Set(lintTargets)); @@ -1303,9 +1302,10 @@ desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex task("lint", ["build-rules"], () => { if (fold.isTravis()) console.log(fold.start("lint")); const fileMatcher = process.env.f || process.env.file || process.env.files; + const files = fileMatcher ? `src/**/${fileMatcher}` - : "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude 'src/lib/*.d.ts'"; + : `Gulpfile.ts scripts/generateLocalizedDiagnosticMessages.ts "scripts/tslint/**/*.ts" "src/**/*.ts" --exclude "src/lib/*.d.ts"`; const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`; console.log("Linting: " + cmd); jake.exec([cmd], { interactive: true }, () => { From cf540198e69551bfccdf823f1bec1669a3cc0019 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 31 Jan 2018 16:22:27 -0800 Subject: [PATCH 21/42] Always get diagnostics when emitting irrespective of whether its declaration only emit The diagnostics reporting and expression resolution caching is quite intermingled at present. Hence when we tried to get the declaration output without getting diagnostics, the resolution for functions return expression is cached but errors arent reported Symbols arent marked as referenced. So at later time when trying to get the diagnostics since the expression resolution is cached, it doesnt even go through all checks For now get diagnostics irrespective of declaration only output to avoid this issue. Fixes #21518 --- src/compiler/checker.ts | 6 ++---- src/compiler/program.ts | 2 +- src/compiler/types.ts | 2 +- src/harness/unittests/tscWatchMode.ts | 27 +++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16b2091733a..a2b0d4b823e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -749,12 +749,10 @@ namespace ts { return _jsxNamespace; } - function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken, ignoreDiagnostics?: boolean) { + function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) { // Ensure we have all the type information in place for this file so that all the // emitter questions of this resolver will return the right information. - if (!ignoreDiagnostics) { - getDiagnostics(sourceFile, cancellationToken); - } + getDiagnostics(sourceFile, cancellationToken); return emitResolver; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6ea50b30f6f..e334c1ce80f 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1179,7 +1179,7 @@ namespace ts { // This is because in the -out scenario all files need to be emitted, and therefore all // files need to be type checked. And the way to specify that all files need to be type // checked is to not pass the file to getEmitResolver. - const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken, emitOnlyDtsFiles); + const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken); performance.mark("beforeEmit"); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 481b91c9276..ce2c10a8dda 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2892,7 +2892,7 @@ namespace ts { // Should not be called directly. Should only be accessed through the Program instance. /* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; /* @internal */ getGlobalDiagnostics(): Diagnostic[]; - /* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken, ignoreDiagnostics?: boolean): EmitResolver; + /* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver; /* @internal */ getNodeCount(): number; /* @internal */ getIdentifierCount(): number; diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index a2b79b00dc7..6915a6ad37d 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -1086,6 +1086,33 @@ namespace ts.tscWatch { // This should be 0 host.checkTimeoutQueueLengthAndRun(0); }); + + it("shouldnt report error about unused function incorrectly when file changes from global to module", () => { + const getFileContent = (asModule: boolean) => ` + function one() {} + ${asModule ? "export " : ""}function two() { + return function three() { + one(); + } + }`; + const file: FileOrFolder = { + path: "/a/b/file.ts", + content: getFileContent(/*asModule*/ false) + }; + const files = [file, libFile]; + const host = createWatchedSystem(files); + const watch = createWatchOfFilesAndCompilerOptions([file.path], host, { + noUnusedLocals: true + }); + checkProgramActualFiles(watch(), files.map(file => file.path)); + checkOutputErrors(host, [], ExpectedOutputErrorsPosition.AfterCompilationStarting); + + file.content = getFileContent(/*asModule*/ true); + host.reloadFS(files); + host.runQueuedTimeoutCallbacks(); + checkProgramActualFiles(watch(), files.map(file => file.path)); + checkOutputErrors(host, [], ExpectedOutputErrorsPosition.AfterFileChangeDetected); + }); }); describe("tsc-watch emit with outFile or out setting", () => { From 11214b9dcd572b674204371ddc4b321102774ea7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 31 Jan 2018 17:15:54 -0800 Subject: [PATCH 22/42] Removing the test added for cancellation during affected list since thats not possible anymore as the affected files would anyways be semantically checked This is just part missed during revert of 0b79f4a --- src/harness/unittests/builder.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/harness/unittests/builder.ts b/src/harness/unittests/builder.ts index 8808a151c04..3a275d39e86 100644 --- a/src/harness/unittests/builder.ts +++ b/src/harness/unittests/builder.ts @@ -70,13 +70,6 @@ namespace ts { // Change e.ts and verify previously b.js as well as a.js get emitted again since previous change was consumed completely but not d.ts program = updateProgramFile(program, "/e.ts", "export function bar3() { }"); assertChanges(["/b.js", "/a.js", "/e.js"]); - - // Cancel in the middle of affected files list after b.js emit - program = updateProgramFile(program, "/b.ts", "export class b { foo2() { c + 1; } }"); - assertChanges(["/b.js", "/a.js"], 1); - // Change e.ts and verify previously b.js as well as a.js get emitted again since previous change was consumed completely but not d.ts - program = updateProgramFile(program, "/e.ts", "export function bar5() { }"); - assertChanges(["/b.js", "/a.js", "/e.js"]); }); }); From df15d5b97732a863591f34ab407db48693c6b147 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 1 Feb 2018 09:24:57 -0800 Subject: [PATCH 23/42] Don't treat class name contextToken as a completion list blocker if it is not the previousToken (#21534) --- src/services/completions.ts | 3 ++- tests/cases/fourslash/completionsKeywordsExtends.ts | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index bce1eadaf26..60dfa8aaaa2 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1921,7 +1921,8 @@ namespace ts.Completions { return isDeclarationName(contextToken) && !isJsxAttribute(contextToken.parent) // Don't block completions if we're in `class C /**/`, because we're *past* the end of the identifier and might want to complete `extends`. - && !(isClassLike(contextToken.parent) && position > previousToken.end); + // If `contextToken !== previousToken`, this is `class C ex/**/`. + && !(isClassLike(contextToken.parent) && (contextToken !== previousToken || position > previousToken.end)); } function isFunctionLikeButNotConstructor(kind: SyntaxKind) { diff --git a/tests/cases/fourslash/completionsKeywordsExtends.ts b/tests/cases/fourslash/completionsKeywordsExtends.ts index 065d30d1286..50c9b741cda 100644 --- a/tests/cases/fourslash/completionsKeywordsExtends.ts +++ b/tests/cases/fourslash/completionsKeywordsExtends.ts @@ -1,6 +1,7 @@ /// ////class C/*a*/ /*b*/ { } +////class C e/*c*/ {} // Tests that `isCompletionListBlocker` is true *at* the class name, but false *after* it. @@ -9,3 +10,6 @@ verify.completionListIsEmpty(); goTo.marker("b"); verify.completionListContains("extends"); + +goTo.marker("c"); +verify.completionListContains("extends"); From d4c84368e58bf2b3edd49e0d9ca6d08e0d2e6f6c Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 1 Feb 2018 10:07:28 -0800 Subject: [PATCH 24/42] Do not clear console in watch mode if --diagnostics or --extendedDiagnostics is specified --- src/compiler/watch.ts | 37 +++++++------ src/harness/unittests/tscWatchMode.ts | 52 +++++++++++-------- tests/baselines/reference/api/typescript.d.ts | 4 +- 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 790295c2254..471a9323a3d 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -31,8 +31,11 @@ namespace ts { }; } - function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic) { - if (system.clearScreen && diagnostic.code !== Diagnostics.Compilation_complete_Watching_for_file_changes.code) { + function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions) { + if (system.clearScreen && + diagnostic.code !== Diagnostics.Compilation_complete_Watching_for_file_changes.code && + !options.extendedDiagnostics && + !options.diagnostics) { system.clearScreen(); } } @@ -42,18 +45,18 @@ namespace ts { */ export function createWatchStatusReporter(system: System, pretty?: boolean): WatchStatusReporter { return pretty ? - (diagnostic: Diagnostic, newLine: string) => { - clearScreenIfNotWatchingForFileChanges(system, diagnostic); - let output = `[${ formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey) }] `; - output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`; - system.write(output); - } : - (diagnostic: Diagnostic, newLine: string) => { - clearScreenIfNotWatchingForFileChanges(system, diagnostic); - let output = new Date().toLocaleTimeString() + " - "; - output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`; - system.write(output); - }; + (diagnostic, newLine, options) => { + clearScreenIfNotWatchingForFileChanges(system, diagnostic, options); + let output = `[${formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey)}] `; + output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`; + system.write(output); + } : + (diagnostic, newLine, options) => { + clearScreenIfNotWatchingForFileChanges(system, diagnostic, options); + let output = new Date().toLocaleTimeString() + " - "; + output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`; + system.write(output); + }; } /** @@ -254,7 +257,7 @@ namespace ts { namespace ts { export type DiagnosticReporter = (diagnostic: Diagnostic) => void; - export type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string) => void; + export type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; export type CreateProgram = (rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: T) => T; export interface WatchCompilerHost { /** @@ -264,7 +267,7 @@ namespace ts { /** If provided, callback to invoke after every new program creation */ afterProgramCreate?(program: T): void; /** If provided, called with Diagnostic message that informs about change in watch status */ - onWatchStatusChange?(diagnostic: Diagnostic, newLine: string): void; + onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; // Only for testing /*@internal*/ @@ -725,7 +728,7 @@ namespace ts { function reportWatchDiagnostic(message: DiagnosticMessage) { if (host.onWatchStatusChange) { - host.onWatchStatusChange(createCompilerDiagnostic(message), newLine); + host.onWatchStatusChange(createCompilerDiagnostic(message), newLine, compilerOptions); } } diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 6915a6ad37d..b6d3099dc77 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -2102,35 +2102,45 @@ declare module "fs" { }); describe("tsc-watch console clearing", () => { - it("clears the console when it starts", () => { + function checkConsoleClearing(diagnostics: boolean, extendedDiagnostics: boolean) { const file = { path: "f.ts", content: "" }; - const host = createWatchedSystem([file]); + const files = [file]; + const host = createWatchedSystem(files); + let clearCount: number | undefined; + checkConsoleClears(); - createWatchOfFilesAndCompilerOptions([file.path], host); + createWatchOfFilesAndCompilerOptions([file.path], host, { diagnostics, extendedDiagnostics }); + checkConsoleClears(); + + file.content = "//"; + host.reloadFS(files); host.runQueuedTimeoutCallbacks(); - host.checkScreenClears(1); + checkConsoleClears(); + + function checkConsoleClears() { + if (clearCount === undefined) { + clearCount = 0; + } + else if (!diagnostics && !extendedDiagnostics) { + clearCount++; + } + host.checkScreenClears(clearCount); + return clearCount; + } + } + + it("without --diagnostics or --extendedDiagnostics", () => { + checkConsoleClearing(/*diagnostics*/ false, /*extendedDiagnostics*/ false); }); - - it("clears the console on recompile", () => { - const file = { - path: "f.ts", - content: "" - }; - const host = createWatchedSystem([file]); - createWatchOfFilesAndCompilerOptions([file.path], host); - - const modifiedFile = { - ...file, - content: "//" - }; - host.reloadFS([modifiedFile]); - host.runQueuedTimeoutCallbacks(); - - host.checkScreenClears(2); + it("with --diagnostics", () => { + checkConsoleClearing(/*diagnostics*/ true, /*extendedDiagnostics*/ false); + }); + it("with --extendedDiagnostics", () => { + checkConsoleClearing(/*diagnostics*/ false, /*extendedDiagnostics*/ true); }); }); } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index bdcc29af76e..6a0a701ca1a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3978,7 +3978,7 @@ declare namespace ts { } declare namespace ts { type DiagnosticReporter = (diagnostic: Diagnostic) => void; - type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string) => void; + type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; type CreateProgram = (rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: T) => T; interface WatchCompilerHost { /** @@ -3988,7 +3988,7 @@ declare namespace ts { /** If provided, callback to invoke after every new program creation */ afterProgramCreate?(program: T): void; /** If provided, called with Diagnostic message that informs about change in watch status */ - onWatchStatusChange?(diagnostic: Diagnostic, newLine: string): void; + onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; useCaseSensitiveFileNames(): boolean; getNewLine(): string; getCurrentDirectory(): string; From 477cba539b1da025c3fb27fe6aa99a7772f7fd29 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 1 Feb 2018 10:51:28 -0800 Subject: [PATCH 25/42] Improve debug failure for failed node cast (#21539) --- src/compiler/core.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 2966582cb39..c2ede12345f 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1454,7 +1454,13 @@ namespace ts { export function cast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut { if (value !== undefined && test(value)) return value; - Debug.fail(`Invalid cast. The supplied value did not pass the test '${Debug.getFunctionName(test)}'.`); + + if (value && typeof (value as any).kind === "number") { + Debug.fail(`Invalid cast. The supplied ${(ts as any).SyntaxKind[(value as any).kind]} did not pass the test '${Debug.getFunctionName(test)}'.`); + } + else { + Debug.fail(`Invalid cast. The supplied value did not pass the test '${Debug.getFunctionName(test)}'.`); + } } /** Does nothing. */ From 39d78b7a2b89cec416fa7ba13d86f63e84b9e527 Mon Sep 17 00:00:00 2001 From: AdityaDaflapurkar Date: Fri, 2 Feb 2018 00:28:31 +0530 Subject: [PATCH 26/42] Fix minor typos in documentation (#21538) --- src/compiler/program.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e334c1ce80f..24a1a0eb106 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -416,7 +416,7 @@ namespace ts { hasInvalidatedResolution: HasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames: boolean, ): boolean { - // If we haven't create a program yet or has changed automatic type directives, then it is not up-to-date + // If we haven't created a program yet or have changed automatic type directives, then it is not up-to-date if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } @@ -457,10 +457,10 @@ namespace ts { } /** - * Determined if source file needs to be re-created even if its text hasnt changed + * Determined if source file needs to be re-created even if its text hasn't changed */ function shouldProgramCreateNewSourceFiles(program: Program, newOptions: CompilerOptions) { - // If any of these options change, we cant reuse old source file even if version match + // If any of these options change, we can't reuse old source file even if version match // The change in options like these could result in change in syntax tree change const oldOptions = program && program.getCompilerOptions(); return oldOptions && ( From f9431210b402dbc7191d439360f8f7c9bd312a5e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 1 Feb 2018 11:37:34 -0800 Subject: [PATCH 27/42] Log more info about compilation --- src/compiler/watch.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 471a9323a3d..08a30810568 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -480,6 +480,7 @@ namespace ts { const watchFilePath = compilerOptions.extendedDiagnostics ? ts.addFilePathWatcherWithLogging : ts.addFilePathWatcher; const watchDirectoryWorker = compilerOptions.extendedDiagnostics ? ts.addDirectoryWatcherWithLogging : ts.addDirectoryWatcher; + writeLog(`Current directory: ${currentDirectory} CaseSensitiveFileNames: ${useCaseSensitiveFileNames}`); if (configFileName) { watchFile(host, configFileName, scheduleProgramReload, writeLog); } @@ -573,6 +574,10 @@ namespace ts { } // Compile the program + if (loggingEnabled) { + writeLog(`CreatingProgramWith::\n roots: ${JSON.stringify(rootFileNames)}\n options: ${JSON.stringify(compilerOptions)}`); + } + const needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !program; hasChangedCompilerOptions = false; resolutionCache.startCachingPerDirectoryResolution(); From 058b2f7f1106cf854e7d288b98937aa2aa62be5e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 1 Feb 2018 12:34:16 -0800 Subject: [PATCH 28/42] Allow boolean literals to be generated from contextual types again (#21503) * Allow boolean literals to be generated from contextual types again * Update fourslash test --- src/compiler/checker.ts | 8 +- .../argumentExpressionContextualTyping.types | 12 +- .../reference/arrayBestCommonTypes.types | 20 +-- tests/baselines/reference/assignToFn.types | 6 +- .../reference/assignmentTypeNarrowing.types | 26 ++-- .../reference/asyncFunctionReturnType.types | 2 +- ...oleanLiteralsContextuallyTypedFromUnion.js | 38 +++++ ...LiteralsContextuallyTypedFromUnion.symbols | 97 ++++++++++++ ...anLiteralsContextuallyTypedFromUnion.types | 139 ++++++++++++++++++ ...utedPropertyNamesContextualType6_ES5.types | 2 +- ...utedPropertyNamesContextualType6_ES6.types | 2 +- .../reference/constEnumPropertyAccess1.types | 2 +- .../reference/contextualTypeWithTuple.types | 2 +- ...rationEmitDestructuringArrayPattern2.types | 8 +- .../declarationsAndAssignments.errors.txt | 16 +- .../declarationsAndAssignments.types | 36 ++--- ...ArrayBindingPatternAndAssignment1ES5.types | 2 +- ...dingPatternAndAssignment1ES5iterable.types | 2 +- ...ArrayBindingPatternAndAssignment1ES6.types | 2 +- ...ingArrayBindingPatternAndAssignment2.types | 2 +- ...bjectBindingPatternAndAssignment1ES5.types | 4 +- ...bjectBindingPatternAndAssignment1ES6.types | 4 +- .../destructuringParameterProperties1.types | 8 +- .../destructuringParameterProperties2.types | 2 +- .../destructuringParameterProperties3.types | 4 +- ...destructuringVariableDeclaration1ES5.types | 8 +- ...uringVariableDeclaration1ES5iterable.types | 8 +- ...destructuringVariableDeclaration1ES6.types | 8 +- ...structuringVariableDeclaration2.errors.txt | 4 +- .../destructuringVariableDeclaration2.types | 10 +- .../disallowLineTerminatorBeforeArrow.types | 4 +- .../reference/duplicateLocalVariable1.types | 28 ++-- .../reference/emitArrowFunction.types | 4 +- .../reference/emitArrowFunctionES6.types | 4 +- .../emitArrowFunctionThisCapturing.types | 2 +- .../emitArrowFunctionThisCapturingES6.types | 2 +- .../excessPropertyCheckWithUnions.errors.txt | 8 +- .../excessPropertyCheckWithUnions.types | 6 +- tests/baselines/reference/for-of36.types | 2 +- tests/baselines/reference/for-of37.types | 4 +- tests/baselines/reference/for-of38.types | 4 +- tests/baselines/reference/for-of39.errors.txt | 24 +-- tests/baselines/reference/for-of40.types | 4 +- tests/baselines/reference/for-of44.types | 4 +- tests/baselines/reference/for-of45.types | 4 +- tests/baselines/reference/for-of46.types | 4 +- tests/baselines/reference/for-of49.types | 4 +- tests/baselines/reference/for-of50.types | 4 +- .../reference/functionOverloads39.types | 6 +- ...nericArgumentCallSigAssignmentCompat.types | 2 +- .../genericTypeArgumentInference1.types | 2 +- .../reference/getAndSetAsMemberNames.types | 2 +- .../reference/getterSetterNonAccessor.types | 6 +- .../reference/indexerWithTuple.types | 2 +- .../reference/interfaceContextualType.types | 16 +- .../interfaceWithPropertyOfEveryType.types | 4 +- .../isomorphicMappedTypeInference.types | 4 +- .../reference/iterableArrayPattern23.types | 4 +- .../reference/iterableArrayPattern24.types | 4 +- .../reference/iterableArrayPattern29.types | 6 +- .../reference/iterableArrayPattern30.types | 6 +- .../reference/jsdocParamTagTypeLiteral.types | 16 +- .../reference/keyofAndIndexedAccess.types | 44 +++--- tests/baselines/reference/literalTypes2.types | 4 +- .../reference/mappedTypeErrors.types | 4 +- .../objectLiteralNormalization.errors.txt | 12 +- .../objectLiteralNormalization.types | 6 +- .../objectLiteralParameterResolution.types | 4 +- tests/baselines/reference/objectSpread.types | 32 ++-- .../reference/objectSpreadNegative.types | 8 +- .../optionalBindingParameters1.types | 2 +- .../optionalBindingParameters2.types | 4 +- ...ptionalBindingParametersInOverloads1.types | 2 +- ...ptionalBindingParametersInOverloads2.types | 4 +- .../reference/overloadResolutionTest1.types | 10 +- .../parserUsingConstructorAsIdentifier.types | 8 +- tests/baselines/reference/parserharness.types | 4 +- ...ivacyCheckAnonymousFunctionParameter.types | 2 +- .../reference/symbolProperty21.errors.txt | 4 +- .../baselines/reference/targetTypeArgs.types | 8 +- .../reference/tsxAttributeResolution6.types | 2 +- .../tsxSpreadAttributesResolution6.errors.txt | 16 +- .../tsxSpreadAttributesResolution6.types | 2 +- tests/baselines/reference/typeAliases.types | 2 +- .../reference/typeGuardsOnClassProperty.types | 4 +- .../reference/typeInferenceLiteralUnion.types | 2 +- ...sTypeParameterConstraintTransitively.types | 8 +- ...TypeParameterConstraintTransitively2.types | 8 +- .../baselines/reference/underscoreTest1.types | 4 +- .../reference/unionTypeInference.types | 2 +- .../useObjectValuesAndEntries1.types | 8 +- ...leanLiteralsContextuallyTypedFromUnion.tsx | 28 ++++ .../fourslash/findAllRefsForMappedType.ts | 2 +- 93 files changed, 614 insertions(+), 316 deletions(-) create mode 100644 tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.js create mode 100644 tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.symbols create mode 100644 tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.types create mode 100644 tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6bb3e7d9706..e75d28aa5e6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18978,13 +18978,9 @@ namespace ts { function isLiteralOfContextualType(candidateType: Type, contextualType: Type): boolean { if (contextualType) { - if (contextualType.flags & TypeFlags.UnionOrIntersection && !(contextualType.flags & TypeFlags.Boolean)) { - // If the contextual type is a union containing both of the 'true' and 'false' types we - // don't consider it a literal context for boolean literals. + if (contextualType.flags & TypeFlags.UnionOrIntersection) { const types = (contextualType).types; - return some(types, t => - !(t.flags & TypeFlags.BooleanLiteral && containsType(types, trueType) && containsType(types, falseType)) && - isLiteralOfContextualType(candidateType, t)); + return some(types, t => isLiteralOfContextualType(candidateType, t)); } if (contextualType.flags & TypeFlags.TypeVariable) { // If the contextual type is a type variable constrained to a primitive type, consider diff --git a/tests/baselines/reference/argumentExpressionContextualTyping.types b/tests/baselines/reference/argumentExpressionContextualTyping.types index 01320b302e6..9a7d3f97d5b 100644 --- a/tests/baselines/reference/argumentExpressionContextualTyping.types +++ b/tests/baselines/reference/argumentExpressionContextualTyping.types @@ -51,14 +51,14 @@ var o1: { x: [string, number], y: { c: boolean, d: string, e: number } } = { x: >c : boolean >d : string >e : number ->{ x: ["string", 1], y: { c: true, d: "world", e: 3 } } : { x: [string, number]; y: { c: boolean; d: string; e: number; }; } +>{ x: ["string", 1], y: { c: true, d: "world", e: 3 } } : { x: [string, number]; y: { c: true; d: string; e: number; }; } >x : [string, number] >["string", 1] : [string, number] >"string" : "string" >1 : 1 ->y : { c: boolean; d: string; e: number; } ->{ c: true, d: "world", e: 3 } : { c: boolean; d: string; e: number; } ->c : boolean +>y : { c: true; d: string; e: number; } +>{ c: true, d: "world", e: 3 } : { c: true; d: string; e: number; } +>c : true >true : true >d : string >"world" : "world" @@ -96,7 +96,7 @@ var array = ["string", 1, true]; var tuple: [string, number, boolean] = ["string", 1, true]; >tuple : [string, number, boolean] ->["string", 1, true] : [string, number, boolean] +>["string", 1, true] : [string, number, true] >"string" : "string" >1 : 1 >true : true @@ -109,7 +109,7 @@ baz(tuple); baz(["string", 1, true]); >baz(["string", 1, true]) : void >baz : (x: [string, number, boolean]) => void ->["string", 1, true] : [string, number, boolean] +>["string", 1, true] : [string, number, true] >"string" : "string" >1 : 1 >true : true diff --git a/tests/baselines/reference/arrayBestCommonTypes.types b/tests/baselines/reference/arrayBestCommonTypes.types index 8d98b90ee31..97a790493d7 100644 --- a/tests/baselines/reference/arrayBestCommonTypes.types +++ b/tests/baselines/reference/arrayBestCommonTypes.types @@ -255,15 +255,15 @@ module EmptyTypes { >x : boolean >y : base >base : base ->[{ x: true, y: new derived() }, { x: false, y: new base() }] : { x: boolean; y: derived; }[] ->{ x: true, y: new derived() } : { x: boolean; y: derived; } ->x : boolean +>[{ x: true, y: new derived() }, { x: false, y: new base() }] : ({ x: true; y: derived; } | { x: false; y: base; })[] +>{ x: true, y: new derived() } : { x: true; y: derived; } +>x : true >true : true >y : derived >new derived() : derived >derived : typeof derived ->{ x: false, y: new base() } : { x: boolean; y: base; } ->x : boolean +>{ x: false, y: new base() } : { x: false; y: base; } +>x : false >false : false >y : base >new base() : base @@ -658,15 +658,15 @@ module NonEmptyTypes { >x : boolean >y : base >base : base ->[{ x: true, y: new derived() }, { x: false, y: new base() }] : { x: boolean; y: base; }[] ->{ x: true, y: new derived() } : { x: boolean; y: derived; } ->x : boolean +>[{ x: true, y: new derived() }, { x: false, y: new base() }] : ({ x: true; y: derived; } | { x: false; y: base; })[] +>{ x: true, y: new derived() } : { x: true; y: derived; } +>x : true >true : true >y : derived >new derived() : derived >derived : typeof derived ->{ x: false, y: new base() } : { x: boolean; y: base; } ->x : boolean +>{ x: false, y: new base() } : { x: false; y: base; } +>x : false >false : false >y : base >new base() : base diff --git a/tests/baselines/reference/assignToFn.types b/tests/baselines/reference/assignToFn.types index 160b8d27557..927f2261fcf 100644 --- a/tests/baselines/reference/assignToFn.types +++ b/tests/baselines/reference/assignToFn.types @@ -13,9 +13,9 @@ module M { var x:I={ f:function(n) { return true; } }; >x : I >I : I ->{ f:function(n) { return true; } } : { f: (n: number) => boolean; } ->f : (n: number) => boolean ->function(n) { return true; } : (n: number) => boolean +>{ f:function(n) { return true; } } : { f: (n: number) => true; } +>f : (n: number) => true +>function(n) { return true; } : (n: number) => true >n : number >true : true diff --git a/tests/baselines/reference/assignmentTypeNarrowing.types b/tests/baselines/reference/assignmentTypeNarrowing.types index 5b43771f086..62d60fa2149 100644 --- a/tests/baselines/reference/assignmentTypeNarrowing.types +++ b/tests/baselines/reference/assignmentTypeNarrowing.types @@ -12,14 +12,14 @@ x; // string >x : string [x] = [true]; ->[x] = [true] : [boolean] +>[x] = [true] : [true] >[x] : [string | number | boolean | RegExp] >x : string | number | boolean | RegExp ->[true] : [boolean] +>[true] : [true] >true : true x; // boolean ->x : boolean +>x : true [x = ""] = [1]; >[x = ""] = [1] : [number] @@ -34,16 +34,16 @@ x; // string | number >x : string | number ({x} = {x: true}); ->({x} = {x: true}) : { x: boolean; } ->{x} = {x: true} : { x: boolean; } +>({x} = {x: true}) : { x: true; } +>{x} = {x: true} : { x: true; } >{x} : { x: string | number | boolean | RegExp; } >x : string | number | boolean | RegExp ->{x: true} : { x: boolean; } ->x : boolean +>{x: true} : { x: true; } +>x : true >true : true x; // boolean ->x : boolean +>x : true ({y: x} = {y: 1}); >({y: x} = {y: 1}) : { y: number; } @@ -59,16 +59,16 @@ x; // number >x : number ({x = ""} = {x: true}); ->({x = ""} = {x: true}) : { x?: boolean; } ->{x = ""} = {x: true} : { x?: boolean; } +>({x = ""} = {x: true}) : { x?: true; } +>{x = ""} = {x: true} : { x?: true; } >{x = ""} : { x?: string | number | boolean | RegExp; } >x : string | number | boolean | RegExp ->{x: true} : { x?: boolean; } ->x : boolean +>{x: true} : { x?: true; } +>x : true >true : true x; // string | boolean ->x : string | boolean +>x : string | true ({y: x = /a/} = {y: 1}); >({y: x = /a/} = {y: 1}) : { y?: number; } diff --git a/tests/baselines/reference/asyncFunctionReturnType.types b/tests/baselines/reference/asyncFunctionReturnType.types index 57fb294e49a..d1dab14ba87 100644 --- a/tests/baselines/reference/asyncFunctionReturnType.types +++ b/tests/baselines/reference/asyncFunctionReturnType.types @@ -15,7 +15,7 @@ async function fAsyncExplicit(): Promise<[number, boolean]> { // This is contextually typed as a tuple. return [1, true]; ->[1, true] : [number, boolean] +>[1, true] : [number, true] >1 : 1 >true : true } diff --git a/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.js b/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.js new file mode 100644 index 00000000000..cf590eeaaaf --- /dev/null +++ b/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.js @@ -0,0 +1,38 @@ +//// [booleanLiteralsContextuallyTypedFromUnion.tsx] +interface A { isIt: true; text: string; } +interface B { isIt: false; value: number; } +type C = A | B; +const isIt = Math.random() > 0.5; +const c: C = isIt ? { isIt, text: 'hey' } : { isIt, value: 123 }; +const cc: C = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 }; + +type ComponentProps = + | { + optionalBool: true; + mandatoryFn: () => void; + } + | { + optionalBool: false; + }; + +let Funk = (_props: ComponentProps) =>
Hello
; + +let Fail1 = () => { }} optionalBool={true} /> +let Fail2 = () => { }} optionalBool={true as true} /> +let True = true as true; +let Fail3 = () => { }} optionalBool={True} /> +let attrs2 = { optionalBool: true as true, mandatoryFn: () => { } } +let Success = () => + +//// [booleanLiteralsContextuallyTypedFromUnion.jsx] +"use strict"; +var isIt = Math.random() > 0.5; +var c = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 }; +var cc = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 }; +var Funk = function (_props) { return
Hello
; }; +var Fail1 = function () { return ; }; +var Fail2 = function () { return ; }; +var True = true; +var Fail3 = function () { return ; }; +var attrs2 = { optionalBool: true, mandatoryFn: function () { } }; +var Success = function () { return ; }; diff --git a/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.symbols b/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.symbols new file mode 100644 index 00000000000..73d3006951f --- /dev/null +++ b/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.symbols @@ -0,0 +1,97 @@ +=== tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx === +interface A { isIt: true; text: string; } +>A : Symbol(A, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 0, 0)) +>isIt : Symbol(A.isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 0, 13)) +>text : Symbol(A.text, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 0, 25)) + +interface B { isIt: false; value: number; } +>B : Symbol(B, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 0, 41)) +>isIt : Symbol(B.isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 1, 13)) +>value : Symbol(B.value, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 1, 26)) + +type C = A | B; +>C : Symbol(C, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 1, 43)) +>A : Symbol(A, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 0, 0)) +>B : Symbol(B, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 0, 41)) + +const isIt = Math.random() > 0.5; +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 3, 5)) +>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.d.ts, --, --)) + +const c: C = isIt ? { isIt, text: 'hey' } : { isIt, value: 123 }; +>c : Symbol(c, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 4, 5)) +>C : Symbol(C, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 1, 43)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 3, 5)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 4, 21)) +>text : Symbol(text, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 4, 27)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 4, 45)) +>value : Symbol(value, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 4, 51)) + +const cc: C = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 }; +>cc : Symbol(cc, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 5, 5)) +>C : Symbol(C, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 1, 43)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 3, 5)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 5, 22)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 3, 5)) +>text : Symbol(text, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 5, 34)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 5, 52)) +>isIt : Symbol(isIt, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 3, 5)) +>value : Symbol(value, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 5, 64)) + +type ComponentProps = +>ComponentProps : Symbol(ComponentProps, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 5, 78)) + + | { + optionalBool: true; +>optionalBool : Symbol(optionalBool, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 8, 7)) + + mandatoryFn: () => void; +>mandatoryFn : Symbol(mandatoryFn, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 9, 27)) + } + | { + optionalBool: false; +>optionalBool : Symbol(optionalBool, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 12, 7)) + + }; + +let Funk = (_props: ComponentProps) =>
Hello
; +>Funk : Symbol(Funk, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 16, 3)) +>_props : Symbol(_props, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 16, 12)) +>ComponentProps : Symbol(ComponentProps, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 5, 78)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45)) + +let Fail1 = () => { }} optionalBool={true} /> +>Fail1 : Symbol(Fail1, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 18, 3)) +>Funk : Symbol(Funk, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 16, 3)) +>mandatoryFn : Symbol(mandatoryFn, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 18, 23)) +>optionalBool : Symbol(optionalBool, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 18, 47)) + +let Fail2 = () => { }} optionalBool={true as true} /> +>Fail2 : Symbol(Fail2, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 19, 3)) +>Funk : Symbol(Funk, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 16, 3)) +>mandatoryFn : Symbol(mandatoryFn, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 19, 23)) +>optionalBool : Symbol(optionalBool, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 19, 47)) + +let True = true as true; +>True : Symbol(True, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 20, 3)) + +let Fail3 = () => { }} optionalBool={True} /> +>Fail3 : Symbol(Fail3, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 21, 3)) +>Funk : Symbol(Funk, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 16, 3)) +>mandatoryFn : Symbol(mandatoryFn, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 21, 23)) +>optionalBool : Symbol(optionalBool, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 21, 47)) +>True : Symbol(True, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 20, 3)) + +let attrs2 = { optionalBool: true as true, mandatoryFn: () => { } } +>attrs2 : Symbol(attrs2, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 22, 3)) +>optionalBool : Symbol(optionalBool, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 22, 14)) +>mandatoryFn : Symbol(mandatoryFn, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 22, 42)) + +let Success = () => +>Success : Symbol(Success, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 23, 3)) +>Funk : Symbol(Funk, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 16, 3)) +>attrs2 : Symbol(attrs2, Decl(booleanLiteralsContextuallyTypedFromUnion.tsx, 22, 3)) + diff --git a/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.types b/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.types new file mode 100644 index 00000000000..4741619c85b --- /dev/null +++ b/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.types @@ -0,0 +1,139 @@ +=== tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx === +interface A { isIt: true; text: string; } +>A : A +>isIt : true +>true : true +>text : string + +interface B { isIt: false; value: number; } +>B : B +>isIt : false +>false : false +>value : number + +type C = A | B; +>C : C +>A : A +>B : B + +const isIt = Math.random() > 0.5; +>isIt : boolean +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + +const c: C = isIt ? { isIt, text: 'hey' } : { isIt, value: 123 }; +>c : C +>C : C +>isIt ? { isIt, text: 'hey' } : { isIt, value: 123 } : { isIt: true; text: string; } | { isIt: false; value: number; } +>isIt : boolean +>{ isIt, text: 'hey' } : { isIt: true; text: string; } +>isIt : true +>text : string +>'hey' : "hey" +>{ isIt, value: 123 } : { isIt: false; value: number; } +>isIt : false +>value : number +>123 : 123 + +const cc: C = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 }; +>cc : C +>C : C +>isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 } : { isIt: true; text: string; } | { isIt: false; value: number; } +>isIt : boolean +>{ isIt: isIt, text: 'hey' } : { isIt: true; text: string; } +>isIt : true +>isIt : true +>text : string +>'hey' : "hey" +>{ isIt: isIt, value: 123 } : { isIt: false; value: number; } +>isIt : false +>isIt : false +>value : number +>123 : 123 + +type ComponentProps = +>ComponentProps : ComponentProps + + | { + optionalBool: true; +>optionalBool : true +>true : true + + mandatoryFn: () => void; +>mandatoryFn : () => void + } + | { + optionalBool: false; +>optionalBool : false +>false : false + + }; + +let Funk = (_props: ComponentProps) =>
Hello
; +>Funk : (_props: ComponentProps) => JSX.Element +>(_props: ComponentProps) =>
Hello
: (_props: ComponentProps) => JSX.Element +>_props : ComponentProps +>ComponentProps : ComponentProps +>
Hello
: JSX.Element +>div : any +>div : any + +let Fail1 = () => { }} optionalBool={true} /> +>Fail1 : () => JSX.Element +>() => { }} optionalBool={true} /> : () => JSX.Element +> { }} optionalBool={true} /> : JSX.Element +>Funk : (_props: ComponentProps) => JSX.Element +>mandatoryFn : () => void +>() => { } : () => void +>optionalBool : true +>true : true + +let Fail2 = () => { }} optionalBool={true as true} /> +>Fail2 : () => JSX.Element +>() => { }} optionalBool={true as true} /> : () => JSX.Element +> { }} optionalBool={true as true} /> : JSX.Element +>Funk : (_props: ComponentProps) => JSX.Element +>mandatoryFn : () => void +>() => { } : () => void +>optionalBool : true +>true as true : true +>true : true +>true : true + +let True = true as true; +>True : true +>true as true : true +>true : true +>true : true + +let Fail3 = () => { }} optionalBool={True} /> +>Fail3 : () => JSX.Element +>() => { }} optionalBool={True} /> : () => JSX.Element +> { }} optionalBool={True} /> : JSX.Element +>Funk : (_props: ComponentProps) => JSX.Element +>mandatoryFn : () => void +>() => { } : () => void +>optionalBool : true +>True : true + +let attrs2 = { optionalBool: true as true, mandatoryFn: () => { } } +>attrs2 : { optionalBool: true; mandatoryFn: () => void; } +>{ optionalBool: true as true, mandatoryFn: () => { } } : { optionalBool: true; mandatoryFn: () => void; } +>optionalBool : true +>true as true : true +>true : true +>true : true +>mandatoryFn : () => void +>() => { } : () => void + +let Success = () => +>Success : () => JSX.Element +>() => : () => JSX.Element +> : JSX.Element +>Funk : (_props: ComponentProps) => JSX.Element +>attrs2 : { optionalBool: true; mandatoryFn: () => void; } + diff --git a/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types b/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types index e0db47e738b..9c89065ac02 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types +++ b/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types @@ -19,7 +19,7 @@ declare function foo(obj: I): T foo({ >foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[] >foo : (obj: I) => T ->{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | boolean | (() => void) | number[]; [x: number]: number | (() => void) | number[]; p: string; 0: () => void; } +>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | true | (() => void) | number[]; [x: number]: number | (() => void) | number[]; p: string; 0: () => void; } p: "", >p : string diff --git a/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types b/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types index 91921c74f7a..03295db5f70 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types +++ b/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types @@ -19,7 +19,7 @@ declare function foo(obj: I): T foo({ >foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[] >foo : (obj: I) => T ->{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | boolean | (() => void) | number[]; [x: number]: number | (() => void) | number[]; p: string; 0: () => void; } +>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | true | (() => void) | number[]; [x: number]: number | (() => void) | number[]; p: string; 0: () => void; } p: "", >p : string diff --git a/tests/baselines/reference/constEnumPropertyAccess1.types b/tests/baselines/reference/constEnumPropertyAccess1.types index 9a8a4a2748f..af9aacd279c 100644 --- a/tests/baselines/reference/constEnumPropertyAccess1.types +++ b/tests/baselines/reference/constEnumPropertyAccess1.types @@ -34,7 +34,7 @@ var o: { >idx : number } = { ->{ 1: true } : { 1: boolean; } +>{ 1: true } : { 1: true; } 1: true >true : true diff --git a/tests/baselines/reference/contextualTypeWithTuple.types b/tests/baselines/reference/contextualTypeWithTuple.types index 92de5b593c1..ddc683739c8 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.types +++ b/tests/baselines/reference/contextualTypeWithTuple.types @@ -15,7 +15,7 @@ var numStrTuple2: [number, string] = [5, "foo", true]; var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; >numStrBoolTuple : [number, string, boolean] ->[5, "foo", true] : [number, string, boolean] +>[5, "foo", true] : [number, string, true] >5 : 5 >"foo" : "foo" >true : true diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types index 807bb154935..097cab978d5 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types @@ -38,14 +38,14 @@ var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello" >10 : 10 >y12 : boolean >false : false ->[1, ["hello", { x12: 5, y12: true }]] : [number, [string, { x12: number; y12: boolean; }]] +>[1, ["hello", { x12: 5, y12: true }]] : [number, [string, { x12: number; y12: true; }]] >1 : 1 ->["hello", { x12: 5, y12: true }] : [string, { x12: number; y12: boolean; }] +>["hello", { x12: 5, y12: true }] : [string, { x12: number; y12: true; }] >"hello" : "hello" ->{ x12: 5, y12: true } : { x12: number; y12: boolean; } +>{ x12: 5, y12: true } : { x12: number; y12: true; } >x12 : number >5 : 5 ->y12 : boolean +>y12 : true >true : true var [x13, y13] = [1, "hello"]; diff --git a/tests/baselines/reference/declarationsAndAssignments.errors.txt b/tests/baselines/reference/declarationsAndAssignments.errors.txt index 4b5ac99499c..64bd8d7e578 100644 --- a/tests/baselines/reference/declarationsAndAssignments.errors.txt +++ b/tests/baselines/reference/declarationsAndAssignments.errors.txt @@ -17,10 +17,10 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,11): tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,14): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,11): error TS2459: Type 'undefined[]' has no property 'a' and no string index signature. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,14): error TS2459: Type 'undefined[]' has no property 'b' and no string index signature. -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,5): error TS2345: Argument of type '[number, [string, { y: boolean; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. - Type '[string, { y: boolean; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. - Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'. - Property 'x' is missing in type '{ y: boolean; }'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,5): error TS2345: Argument of type '[number, [string, { y: false; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. + Type '[string, { y: false; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. + Type '{ y: false; }' is not assignable to type '{ x: any; y?: boolean; }'. + Property 'x' is missing in type '{ y: false; }'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,6): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): error TS2322: Type 'number' is not assignable to type 'string'. @@ -171,10 +171,10 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): f14([2, ["abc", { x: 0 }]]); f14([2, ["abc", { y: false }]]); // Error, no x ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, [string, { y: boolean; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. -!!! error TS2345: Type '[string, { y: boolean; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. -!!! error TS2345: Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'. -!!! error TS2345: Property 'x' is missing in type '{ y: boolean; }'. +!!! error TS2345: Argument of type '[number, [string, { y: false; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. +!!! error TS2345: Type '[string, { y: false; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. +!!! error TS2345: Type '{ y: false; }' is not assignable to type '{ x: any; y?: boolean; }'. +!!! error TS2345: Property 'x' is missing in type '{ y: false; }'. module M { export var [a, b] = [1, 2]; diff --git a/tests/baselines/reference/declarationsAndAssignments.types b/tests/baselines/reference/declarationsAndAssignments.types index 6bd5b8da7cb..31e9920c630 100644 --- a/tests/baselines/reference/declarationsAndAssignments.types +++ b/tests/baselines/reference/declarationsAndAssignments.types @@ -363,14 +363,14 @@ function f12() { >10 : 10 >y : boolean >false : false ->[1, ["hello", { x: 5, y: true }]] : [number, [string, { x: number; y: boolean; }]] +>[1, ["hello", { x: 5, y: true }]] : [number, [string, { x: number; y: true; }]] >1 : 1 ->["hello", { x: 5, y: true }] : [string, { x: number; y: boolean; }] +>["hello", { x: 5, y: true }] : [string, { x: number; y: true; }] >"hello" : "hello" ->{ x: 5, y: true } : { x: number; y: boolean; } +>{ x: 5, y: true } : { x: number; y: true; } >x : number >5 : 5 ->y : boolean +>y : true >true : true var a: number; @@ -433,14 +433,14 @@ function f14([a = 1, [b = "hello", { x, y: c = false }]]) { f14([2, ["abc", { x: 0, y: true }]]); >f14([2, ["abc", { x: 0, y: true }]]) : void >f14 : ([a, [b, { x, y: c }]]: [number, [string, { x: any; y?: boolean; }]]) => void ->[2, ["abc", { x: 0, y: true }]] : [number, [string, { x: number; y: boolean; }]] +>[2, ["abc", { x: 0, y: true }]] : [number, [string, { x: number; y: true; }]] >2 : 2 ->["abc", { x: 0, y: true }] : [string, { x: number; y: boolean; }] +>["abc", { x: 0, y: true }] : [string, { x: number; y: true; }] >"abc" : "abc" ->{ x: 0, y: true } : { x: number; y: boolean; } +>{ x: 0, y: true } : { x: number; y: true; } >x : number >0 : 0 ->y : boolean +>y : true >true : true f14([2, ["abc", { x: 0 }]]); @@ -534,8 +534,8 @@ f17({ a: "hello" }); f17({ c: true }); >f17({ c: true }) : void >f17 : ({ a, b, c }: { a?: string; b?: number; c?: boolean; }) => void ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true f17(f15()); @@ -818,47 +818,47 @@ function f21() { >true : true [...a] = [1, "hello", true]; ->[...a] = [1, "hello", true] : (string | number | boolean)[] +>[...a] = [1, "hello", true] : (string | number | true)[] >[...a] : (string | number | boolean)[] >...a : string | number | boolean >a : (string | number | boolean)[] ->[1, "hello", true] : (string | number | boolean)[] +>[1, "hello", true] : (string | number | true)[] >1 : 1 >"hello" : "hello" >true : true [x, ...a] = [1, "hello", true]; ->[x, ...a] = [1, "hello", true] : (string | number | boolean)[] +>[x, ...a] = [1, "hello", true] : (string | number | true)[] >[x, ...a] : (string | number | boolean)[] >x : string | number | boolean >...a : string | number | boolean >a : (string | number | boolean)[] ->[1, "hello", true] : (string | number | boolean)[] +>[1, "hello", true] : (string | number | true)[] >1 : 1 >"hello" : "hello" >true : true [x, y, ...a] = [1, "hello", true]; ->[x, y, ...a] = [1, "hello", true] : (string | number | boolean)[] +>[x, y, ...a] = [1, "hello", true] : (string | number | true)[] >[x, y, ...a] : (string | number | boolean)[] >x : string | number | boolean >y : string | number | boolean >...a : string | number | boolean >a : (string | number | boolean)[] ->[1, "hello", true] : (string | number | boolean)[] +>[1, "hello", true] : (string | number | true)[] >1 : 1 >"hello" : "hello" >true : true [x, y, z, ...a] = [1, "hello", true]; ->[x, y, z, ...a] = [1, "hello", true] : (string | number | boolean)[] +>[x, y, z, ...a] = [1, "hello", true] : (string | number | true)[] >[x, y, z, ...a] : (string | number | boolean)[] >x : string | number | boolean >y : string | number | boolean >z : string | number | boolean >...a : string | number | boolean >a : (string | number | boolean)[] ->[1, "hello", true] : (string | number | boolean)[] +>[1, "hello", true] : (string | number | true)[] >1 : 1 >"hello" : "hello" >true : true diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types index bddce3cc391..3ad1bfa1dd2 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types @@ -109,7 +109,7 @@ var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number >c6 : boolean ->[[1], true] : [[number], boolean] +>[[1], true] : [[number], true] >[1] : [number] >1 : 1 >true : true diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types index e17e37f4980..1c46f553d4d 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types @@ -109,7 +109,7 @@ var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number >c6 : boolean ->[[1], true] : [[number], boolean] +>[[1], true] : [[number], true] >[1] : [number] >1 : 1 >true : true diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types index 0c6b87eb46a..3a51965df31 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types @@ -109,7 +109,7 @@ var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number >c6 : boolean ->[[1], true] : [[number], boolean] +>[[1], true] : [[number], true] >[1] : [number] >1 : 1 >true : true diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types index 9c29ea1a423..73640f27a59 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types @@ -86,7 +86,7 @@ function foo(idx: number): F { >F : F return { ->{ 2: true } : { 2: boolean; } +>{ 2: true } : { 2: true; } 2: true >true : true diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types index 2319640a1cb..203815fa9c8 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types @@ -69,7 +69,7 @@ function foo(): F { >F : F return { ->{ 1: true } : { 1: boolean; } +>{ 1: true } : { 1: true; } 1: true >true : true @@ -82,7 +82,7 @@ function bar(): F { >F : F return { ->{ 2: true } : { 2: boolean; } +>{ 2: true } : { 2: true; } 2: true >true : true diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types index 1c6ccb524fe..1c3d1f4d00c 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types @@ -69,7 +69,7 @@ function foo(): F { >F : F return { ->{ 1: true } : { 1: boolean; } +>{ 1: true } : { 1: true; } 1: true >true : true @@ -82,7 +82,7 @@ function bar(): F { >F : F return { ->{ 2: true } : { 2: boolean; } +>{ 2: true } : { 2: true; } 2: true >true : true diff --git a/tests/baselines/reference/destructuringParameterProperties1.types b/tests/baselines/reference/destructuringParameterProperties1.types index a294686569b..e4c9964fb13 100644 --- a/tests/baselines/reference/destructuringParameterProperties1.types +++ b/tests/baselines/reference/destructuringParameterProperties1.types @@ -104,12 +104,12 @@ var c3 = new C3({x: 0, y: "", z: false}); >c3 : C3 >new C3({x: 0, y: "", z: false}) : C3 >C3 : typeof C3 ->{x: 0, y: "", z: false} : { x: number; y: string; z: boolean; } +>{x: 0, y: "", z: false} : { x: number; y: string; z: false; } >x : number >0 : 0 >y : string >"" : "" ->z : boolean +>z : false >false : false c3 = new C3({x: 0, "y": "y", z: true}); @@ -117,11 +117,11 @@ c3 = new C3({x: 0, "y": "y", z: true}); >c3 : C3 >new C3({x: 0, "y": "y", z: true}) : C3 >C3 : typeof C3 ->{x: 0, "y": "y", z: true} : { x: number; "y": string; z: boolean; } +>{x: 0, "y": "y", z: true} : { x: number; "y": string; z: true; } >x : number >0 : 0 >"y" : "y" ->z : boolean +>z : true >true : true var [c3_x, c3_y, c3_z] = [c3.x, c3.y, c3.z]; diff --git a/tests/baselines/reference/destructuringParameterProperties2.types b/tests/baselines/reference/destructuringParameterProperties2.types index 1edbce3a820..3b9ea8d273f 100644 --- a/tests/baselines/reference/destructuringParameterProperties2.types +++ b/tests/baselines/reference/destructuringParameterProperties2.types @@ -103,7 +103,7 @@ var y = new C1(10, [0, "", true]); >new C1(10, [0, "", true]) : C1 >C1 : typeof C1 >10 : 10 ->[0, "", true] : [number, string, boolean] +>[0, "", true] : [number, string, true] >0 : 0 >"" : "" >true : true diff --git a/tests/baselines/reference/destructuringParameterProperties3.types b/tests/baselines/reference/destructuringParameterProperties3.types index f9ce7a8613b..34c683941c7 100644 --- a/tests/baselines/reference/destructuringParameterProperties3.types +++ b/tests/baselines/reference/destructuringParameterProperties3.types @@ -82,7 +82,7 @@ var x = new C1(undefined, [0, true, ""]); >new C1(undefined, [0, true, ""]) : C1 >C1 : typeof C1 >undefined : undefined ->[0, true, ""] : [number, boolean, string] +>[0, true, ""] : [number, true, string] >0 : 0 >true : true >"" : "" @@ -110,7 +110,7 @@ var y = new C1(10, [0, true, true]); >new C1(10, [0, true, true]) : C1 >C1 : typeof C1 >10 : 10 ->[0, true, true] : [number, boolean, boolean] +>[0, true, true] : [number, true, true] >0 : 0 >true : true >true : true diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types index 125fd8a2c21..c3fbcb22d5d 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types @@ -16,7 +16,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [["hello"]], true]; >a3 : number >a4 : string >a5 : boolean ->[1, [["hello"]], true] : [number, [[string]], boolean] +>[1, [["hello"]], true] : [number, [[string]], true] >1 : 1 >[["hello"]] : [[string]] >["hello"] : [string] @@ -52,11 +52,11 @@ var [b2 = 3, b3 = true, b4 = temp] = [3, false, { t1: false, t2: "hello" }]; >true : true >b4 : { t1: boolean; t2: string; } >temp : { t1: boolean; t2: string; } ->[3, false, { t1: false, t2: "hello" }] : [number, boolean, { t1: boolean; t2: string; }] +>[3, false, { t1: false, t2: "hello" }] : [number, false, { t1: false; t2: string; }] >3 : 3 >false : false ->{ t1: false, t2: "hello" } : { t1: boolean; t2: string; } ->t1 : boolean +>{ t1: false, t2: "hello" } : { t1: false; t2: string; } +>t1 : false >false : false >t2 : string >"hello" : "hello" diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types index d97bb20d24a..d52e7a51da8 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types @@ -16,7 +16,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [["hello"]], true]; >a3 : number >a4 : string >a5 : boolean ->[1, [["hello"]], true] : [number, [[string]], boolean] +>[1, [["hello"]], true] : [number, [[string]], true] >1 : 1 >[["hello"]] : [[string]] >["hello"] : [string] @@ -52,11 +52,11 @@ var [b2 = 3, b3 = true, b4 = temp] = [3, false, { t1: false, t2: "hello" }]; >true : true >b4 : { t1: boolean; t2: string; } >temp : { t1: boolean; t2: string; } ->[3, false, { t1: false, t2: "hello" }] : [number, boolean, { t1: boolean; t2: string; }] +>[3, false, { t1: false, t2: "hello" }] : [number, false, { t1: false; t2: string; }] >3 : 3 >false : false ->{ t1: false, t2: "hello" } : { t1: boolean; t2: string; } ->t1 : boolean +>{ t1: false, t2: "hello" } : { t1: false; t2: string; } +>t1 : false >false : false >t2 : string >"hello" : "hello" diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types index ec42861b2fc..ce4dfe0679d 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types @@ -16,7 +16,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [["hello"]], true]; >a3 : number >a4 : string >a5 : boolean ->[1, [["hello"]], true] : [number, [[string]], boolean] +>[1, [["hello"]], true] : [number, [[string]], true] >1 : 1 >[["hello"]] : [[string]] >["hello"] : [string] @@ -52,11 +52,11 @@ var [b2 = 3, b3 = true, b4 = temp] = [3, false, { t1: false, t2: "hello" }]; >true : true >b4 : { t1: boolean; t2: string; } >temp : { t1: boolean; t2: string; } ->[3, false, { t1: false, t2: "hello" }] : [number, boolean, { t1: boolean; t2: string; }] +>[3, false, { t1: false, t2: "hello" }] : [number, false, { t1: false; t2: string; }] >3 : 3 >false : false ->{ t1: false, t2: "hello" } : { t1: boolean; t2: string; } ->t1 : boolean +>{ t1: false, t2: "hello" } : { t1: false; t2: string; } +>t1 : false >false : false >t2 : string >"hello" : "hello" diff --git a/tests/baselines/reference/destructuringVariableDeclaration2.errors.txt b/tests/baselines/reference/destructuringVariableDeclaration2.errors.txt index 7658de962d9..c831b10a467 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringVariableDeclaration2.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringVariableDeclaration2.ts(3,5): error TS2322: Type '{ a1: boolean; a2: number; }' is not assignable to type '{ a1: number; a2: string; }'. Types of property 'a1' are incompatible. Type 'boolean' is not assignable to type 'number'. -tests/cases/conformance/es6/destructuring/destructuringVariableDeclaration2.ts(4,5): error TS2322: Type '[number, [[boolean]], boolean]' is not assignable to type '[number, [[string]], boolean]'. +tests/cases/conformance/es6/destructuring/destructuringVariableDeclaration2.ts(4,5): error TS2322: Type '[number, [[boolean]], true]' is not assignable to type '[number, [[string]], boolean]'. Type '[[boolean]]' is not assignable to type '[[string]]'. Type '[boolean]' is not assignable to type '[string]'. Type 'boolean' is not assignable to type 'string'. @@ -19,7 +19,7 @@ tests/cases/conformance/es6/destructuring/destructuringVariableDeclaration2.ts(1 !!! error TS2322: Type 'boolean' is not assignable to type 'number'. var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [[false]], true]; // Error ~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '[number, [[boolean]], boolean]' is not assignable to type '[number, [[string]], boolean]'. +!!! error TS2322: Type '[number, [[boolean]], true]' is not assignable to type '[number, [[string]], boolean]'. !!! error TS2322: Type '[[boolean]]' is not assignable to type '[[string]]'. !!! error TS2322: Type '[boolean]' is not assignable to type '[string]'. !!! error TS2322: Type 'boolean' is not assignable to type 'string'. diff --git a/tests/baselines/reference/destructuringVariableDeclaration2.types b/tests/baselines/reference/destructuringVariableDeclaration2.types index 3d7941b5971..666967f91bb 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration2.types +++ b/tests/baselines/reference/destructuringVariableDeclaration2.types @@ -16,7 +16,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [[false]], true]; // >a3 : number >a4 : string >a5 : boolean ->[1, [[false]], true] : [number, [[boolean]], boolean] +>[1, [[false]], true] : [number, [[boolean]], true] >1 : 1 >[[false]] : [[boolean]] >[false] : [boolean] @@ -38,13 +38,13 @@ var [b0 = 3, b1 = true, b2 = temp] = [3, false, { t1: false, t2: 5}]; // Error >3 : 3 >b1 : boolean >true : true ->b2 : { t1: boolean; t2: string; } | { t1: boolean; t2: number; } +>b2 : { t1: boolean; t2: string; } | { t1: false; t2: number; } >temp : { t1: boolean; t2: string; } ->[3, false, { t1: false, t2: 5}] : [number, boolean, { t1: boolean; t2: number; }] +>[3, false, { t1: false, t2: 5}] : [number, false, { t1: false; t2: number; }] >3 : 3 >false : false ->{ t1: false, t2: 5} : { t1: boolean; t2: number; } ->t1 : boolean +>{ t1: false, t2: 5} : { t1: false; t2: number; } +>t1 : false >false : false >t2 : number >5 : 5 diff --git a/tests/baselines/reference/disallowLineTerminatorBeforeArrow.types b/tests/baselines/reference/disallowLineTerminatorBeforeArrow.types index 5684c3c7dc4..8cab0d7834e 100644 --- a/tests/baselines/reference/disallowLineTerminatorBeforeArrow.types +++ b/tests/baselines/reference/disallowLineTerminatorBeforeArrow.types @@ -150,7 +150,7 @@ function foo(func: () => boolean) { } foo(() >foo(() => true) : void >foo : (func: () => boolean) => void ->() => true : () => boolean +>() => true : () => true => true); >true : true @@ -158,7 +158,7 @@ foo(() foo(() >foo(() => { return false; }) : void >foo : (func: () => boolean) => void ->() => { return false; } : () => boolean +>() => { return false; } : () => false => { return false; }); >false : false diff --git a/tests/baselines/reference/duplicateLocalVariable1.types b/tests/baselines/reference/duplicateLocalVariable1.types index e9c475aef69..d65cb3779e2 100644 --- a/tests/baselines/reference/duplicateLocalVariable1.types +++ b/tests/baselines/reference/duplicateLocalVariable1.types @@ -230,7 +230,7 @@ export var tests: TestRunner = (function () { >new TestCase("Basic test", function () { return true; }) : TestCase >TestCase : typeof TestCase >"Basic test" : "Basic test" ->function () { return true; } : () => boolean +>function () { return true; } : () => true >true : true testRunner.addTest(new TestCase("Test for any error", function () { throw new Error(); return false; }, "")); @@ -241,7 +241,7 @@ export var tests: TestRunner = (function () { >new TestCase("Test for any error", function () { throw new Error(); return false; }, "") : TestCase >TestCase : typeof TestCase >"Test for any error" : "Test for any error" ->function () { throw new Error(); return false; } : () => boolean +>function () { throw new Error(); return false; } : () => false >new Error() : Error >Error : ErrorConstructor >false : false @@ -255,7 +255,7 @@ export var tests: TestRunner = (function () { >new TestCase("Test RegEx error message match", function () { throw new Error("Should also pass"); return false; }, "Should [also]+ pass") : TestCase >TestCase : typeof TestCase >"Test RegEx error message match" : "Test RegEx error message match" ->function () { throw new Error("Should also pass"); return false; } : () => boolean +>function () { throw new Error("Should also pass"); return false; } : () => false >new Error("Should also pass") : Error >Error : ErrorConstructor >"Should also pass" : "Should also pass" @@ -1104,7 +1104,7 @@ export var tests: TestRunner = (function () { >"Check saving a file" : "Check saving a file" function () { ->function () { var filename = TestFileDir + "\\tmpUTF16LE.txt"; var fb = new FileManager.FileBuffer(14); fb.writeUtf16leBom(); var chars = [0x0054, 0x00E8, 0x1D23, 0x2020, 0x000D, 0x000A]; chars.forEach(function (val) { fb.writeUtf16CodePoint(val, false); }); fb.save(filename); var savedFile = new FileManager.FileBuffer(filename); if (savedFile.encoding !== 'utf16le') { throw Error("Incorrect encoding"); } var expectedBytes = [0xFF, 0xFE, 0x54, 0x00, 0xE8, 0x00, 0x23, 0x1D, 0x20, 0x20, 0x0D, 0x00, 0x0A, 0x00] savedFile.index = 0; expectedBytes.forEach(function (val) { var byteVal = savedFile.readByte(); if (byteVal !== val) { throw Error("Incorrect byte value"); } }); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\tmpUTF16LE.txt"; var fb = new FileManager.FileBuffer(14); fb.writeUtf16leBom(); var chars = [0x0054, 0x00E8, 0x1D23, 0x2020, 0x000D, 0x000A]; chars.forEach(function (val) { fb.writeUtf16CodePoint(val, false); }); fb.save(filename); var savedFile = new FileManager.FileBuffer(filename); if (savedFile.encoding !== 'utf16le') { throw Error("Incorrect encoding"); } var expectedBytes = [0xFF, 0xFE, 0x54, 0x00, 0xE8, 0x00, 0x23, 0x1D, 0x20, 0x20, 0x0D, 0x00, 0x0A, 0x00] savedFile.index = 0; expectedBytes.forEach(function (val) { var byteVal = savedFile.readByte(); if (byteVal !== val) { throw Error("Incorrect byte value"); } }); return true; } : () => true var filename = TestFileDir + "\\tmpUTF16LE.txt"; >filename : string @@ -1243,7 +1243,7 @@ export var tests: TestRunner = (function () { >"Check reading past buffer asserts" : "Check reading past buffer asserts" function () { ->function () { var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); var result = fb.readByte(200); return true; } : () => boolean +>function () { var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); var result = fb.readByte(200); return true; } : () => true var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); >fb : any @@ -1279,7 +1279,7 @@ export var tests: TestRunner = (function () { >"Check writing past buffer asserts" : "Check writing past buffer asserts" function () { ->function () { var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); fb.writeByte(5, 200); return true; } : () => boolean +>function () { var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); fb.writeByte(5, 200); return true; } : () => true var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); >fb : any @@ -1473,7 +1473,7 @@ export var tests: TestRunner = (function () { >"Write non-BMP utf8 chars" : "Write non-BMP utf8 chars" function () { ->function () { var filename = TestFileDir + "\\tmpUTF8nonBmp.txt"; var fb = new FileManager.FileBuffer(15); var chars = [0x10480, 0x10481, 0x10482, 0x54, 0x68, 0x69]; chars.forEach(function (val) { fb.writeUtf8CodePoint(val); }); fb.save(filename); var savedFile = new FileManager.FileBuffer(filename); if (savedFile.encoding !== 'utf8') { throw Error("Incorrect encoding"); } var expectedBytes = [0xF0, 0x90, 0x92, 0x80, 0xF0, 0x90, 0x92, 0x81, 0xF0, 0x90, 0x92, 0x82, 0x54, 0x68, 0x69]; expectedBytes.forEach(function (val) { var byteVal = savedFile.readByte(); if (byteVal !== val) { throw Error("Incorrect byte value"); } }); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\tmpUTF8nonBmp.txt"; var fb = new FileManager.FileBuffer(15); var chars = [0x10480, 0x10481, 0x10482, 0x54, 0x68, 0x69]; chars.forEach(function (val) { fb.writeUtf8CodePoint(val); }); fb.save(filename); var savedFile = new FileManager.FileBuffer(filename); if (savedFile.encoding !== 'utf8') { throw Error("Incorrect encoding"); } var expectedBytes = [0xF0, 0x90, 0x92, 0x80, 0xF0, 0x90, 0x92, 0x81, 0xF0, 0x90, 0x92, 0x82, 0x54, 0x68, 0x69]; expectedBytes.forEach(function (val) { var byteVal = savedFile.readByte(); if (byteVal !== val) { throw Error("Incorrect byte value"); } }); return true; } : () => true var filename = TestFileDir + "\\tmpUTF8nonBmp.txt"; >filename : string @@ -1599,7 +1599,7 @@ export var tests: TestRunner = (function () { >"Test invalid lead UTF8 byte" : "Test invalid lead UTF8 byte" function () { ->function () { var filename = TestFileDir + "\\utf8BadLeadByte.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\utf8BadLeadByte.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => true var filename = TestFileDir + "\\utf8BadLeadByte.txt"; >filename : string @@ -1631,7 +1631,7 @@ export var tests: TestRunner = (function () { >"Test invalid tail UTF8 byte" : "Test invalid tail UTF8 byte" function () { ->function () { var filename = TestFileDir + "\\utf8InvalidTail.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\utf8InvalidTail.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => true var filename = TestFileDir + "\\utf8InvalidTail.txt"; >filename : string @@ -1663,7 +1663,7 @@ export var tests: TestRunner = (function () { >"Test ANSI fails validation" : "Test ANSI fails validation" function () { ->function () { var filename = TestFileDir + "\\ansi.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\ansi.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => true var filename = TestFileDir + "\\ansi.txt"; >filename : string @@ -1695,7 +1695,7 @@ export var tests: TestRunner = (function () { >"Test UTF-16LE with invalid surrogate trail fails" : "Test UTF-16LE with invalid surrogate trail fails" function () { ->function () { var filename = TestFileDir + "\\utf16leInvalidSurrogate.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\utf16leInvalidSurrogate.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => true var filename = TestFileDir + "\\utf16leInvalidSurrogate.txt"; >filename : string @@ -1727,7 +1727,7 @@ export var tests: TestRunner = (function () { >"Test UTF-16BE with invalid surrogate head fails" : "Test UTF-16BE with invalid surrogate head fails" function () { ->function () { var filename = TestFileDir + "\\UTF16BEInvalidSurrogate.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\UTF16BEInvalidSurrogate.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => true var filename = TestFileDir + "\\UTF16BEInvalidSurrogate.txt"; >filename : string @@ -1759,7 +1759,7 @@ export var tests: TestRunner = (function () { >"Test UTF-16LE with missing trail surrogate fails" : "Test UTF-16LE with missing trail surrogate fails" function () { ->function () { var filename = TestFileDir + "\\utf16leMissingTrailSurrogate.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\utf16leMissingTrailSurrogate.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => true var filename = TestFileDir + "\\utf16leMissingTrailSurrogate.txt"; >filename : string @@ -1851,7 +1851,7 @@ export var tests: TestRunner = (function () { >"Test file with control character" : "Test file with control character" function () { ->function () { var filename = TestFileDir + "\\controlChar.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => boolean +>function () { var filename = TestFileDir + "\\controlChar.txt"; var fb = new FileManager.FileBuffer(filename); return true; } : () => true var filename = TestFileDir + "\\controlChar.txt"; >filename : string diff --git a/tests/baselines/reference/emitArrowFunction.types b/tests/baselines/reference/emitArrowFunction.types index 232a512cd0a..aa0627632c8 100644 --- a/tests/baselines/reference/emitArrowFunction.types +++ b/tests/baselines/reference/emitArrowFunction.types @@ -31,12 +31,12 @@ function foo(func: () => boolean) { } foo(() => true); >foo(() => true) : void >foo : (func: () => boolean) => void ->() => true : () => boolean +>() => true : () => true >true : true foo(() => { return false; }); >foo(() => { return false; }) : void >foo : (func: () => boolean) => void ->() => { return false; } : () => boolean +>() => { return false; } : () => false >false : false diff --git a/tests/baselines/reference/emitArrowFunctionES6.types b/tests/baselines/reference/emitArrowFunctionES6.types index 91ba674e180..314d5e464b7 100644 --- a/tests/baselines/reference/emitArrowFunctionES6.types +++ b/tests/baselines/reference/emitArrowFunctionES6.types @@ -31,13 +31,13 @@ function foo(func: () => boolean) { } foo(() => true); >foo(() => true) : void >foo : (func: () => boolean) => void ->() => true : () => boolean +>() => true : () => true >true : true foo(() => { return false; }); >foo(() => { return false; }) : void >foo : (func: () => boolean) => void ->() => { return false; } : () => boolean +>() => { return false; } : () => false >false : false // Binding patterns in arrow functions diff --git a/tests/baselines/reference/emitArrowFunctionThisCapturing.types b/tests/baselines/reference/emitArrowFunctionThisCapturing.types index d44419f7bf8..0ef27791d17 100644 --- a/tests/baselines/reference/emitArrowFunctionThisCapturing.types +++ b/tests/baselines/reference/emitArrowFunctionThisCapturing.types @@ -32,7 +32,7 @@ function foo(func: () => boolean) { } foo(() => { >foo(() => { this.age = 100; return true;}) : void >foo : (func: () => boolean) => void ->() => { this.age = 100; return true;} : () => boolean +>() => { this.age = 100; return true;} : () => true this.age = 100; >this.age = 100 : 100 diff --git a/tests/baselines/reference/emitArrowFunctionThisCapturingES6.types b/tests/baselines/reference/emitArrowFunctionThisCapturingES6.types index 8a29ca8b5d9..3c20bfd195c 100644 --- a/tests/baselines/reference/emitArrowFunctionThisCapturingES6.types +++ b/tests/baselines/reference/emitArrowFunctionThisCapturingES6.types @@ -32,7 +32,7 @@ function foo(func: () => boolean){ } foo(() => { >foo(() => { this.age = 100; return true;}) : void >foo : (func: () => boolean) => void ->() => { this.age = 100; return true;} : () => boolean +>() => { this.age = 100; return true;} : () => true this.age = 100; >this.age = 100 : 100 diff --git a/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt b/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt index f5e0550033d..958bf059324 100644 --- a/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt +++ b/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt @@ -13,8 +13,8 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(39,1): error TS2322: Type Type '{ tag: "A"; }' is not assignable to type '{ tag: "C"; }'. Types of property 'tag' are incompatible. Type '"A"' is not assignable to type '"C"'. -tests/cases/compiler/excessPropertyCheckWithUnions.ts(40,1): error TS2322: Type '{ tag: "A"; z: boolean; }' is not assignable to type 'Ambiguous'. - Type '{ tag: "A"; z: boolean; }' is not assignable to type '{ tag: "C"; }'. +tests/cases/compiler/excessPropertyCheckWithUnions.ts(40,1): error TS2322: Type '{ tag: "A"; z: true; }' is not assignable to type 'Ambiguous'. + Type '{ tag: "A"; z: true; }' is not assignable to type '{ tag: "C"; }'. Types of property 'tag' are incompatible. Type '"A"' is not assignable to type '"C"'. tests/cases/compiler/excessPropertyCheckWithUnions.ts(49,35): error TS2322: Type '{ a: 1; b: 1; first: string; second: string; }' is not assignable to type 'Overlapping'. @@ -91,8 +91,8 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2322: Type !!! error TS2322: Type '"A"' is not assignable to type '"C"'. amb = { tag: "A", z: true } ~~~ -!!! error TS2322: Type '{ tag: "A"; z: boolean; }' is not assignable to type 'Ambiguous'. -!!! error TS2322: Type '{ tag: "A"; z: boolean; }' is not assignable to type '{ tag: "C"; }'. +!!! error TS2322: Type '{ tag: "A"; z: true; }' is not assignable to type 'Ambiguous'. +!!! error TS2322: Type '{ tag: "A"; z: true; }' is not assignable to type '{ tag: "C"; }'. !!! error TS2322: Types of property 'tag' are incompatible. !!! error TS2322: Type '"A"' is not assignable to type '"C"'. diff --git a/tests/baselines/reference/excessPropertyCheckWithUnions.types b/tests/baselines/reference/excessPropertyCheckWithUnions.types index 41a8bb67a03..2c48de4d67b 100644 --- a/tests/baselines/reference/excessPropertyCheckWithUnions.types +++ b/tests/baselines/reference/excessPropertyCheckWithUnions.types @@ -139,12 +139,12 @@ amb = { tag: "A" } >"A" : "A" amb = { tag: "A", z: true } ->amb = { tag: "A", z: true } : { tag: "A"; z: boolean; } +>amb = { tag: "A", z: true } : { tag: "A"; z: true; } >amb : Ambiguous ->{ tag: "A", z: true } : { tag: "A"; z: boolean; } +>{ tag: "A", z: true } : { tag: "A"; z: true; } >tag : "A" >"A" : "A" ->z : boolean +>z : true >true : true type Overlapping = diff --git a/tests/baselines/reference/for-of36.types b/tests/baselines/reference/for-of36.types index 54d3b774ff5..1448c212371 100644 --- a/tests/baselines/reference/for-of36.types +++ b/tests/baselines/reference/for-of36.types @@ -1,7 +1,7 @@ === tests/cases/conformance/es6/for-ofStatements/for-of36.ts === var tuple: [string, boolean] = ["", true]; >tuple : [string, boolean] ->["", true] : [string, boolean] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/for-of37.types b/tests/baselines/reference/for-of37.types index f396b7d3184..1168921596e 100644 --- a/tests/baselines/reference/for-of37.types +++ b/tests/baselines/reference/for-of37.types @@ -3,8 +3,8 @@ var map = new Map([["", true]]); >map : Map >new Map([["", true]]) : Map >Map : MapConstructor ->[["", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/for-of38.types b/tests/baselines/reference/for-of38.types index 7e8f599f06b..e2201d24394 100644 --- a/tests/baselines/reference/for-of38.types +++ b/tests/baselines/reference/for-of38.types @@ -3,8 +3,8 @@ var map = new Map([["", true]]); >map : Map >new Map([["", true]]) : Map >Map : MapConstructor ->[["", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/for-of39.errors.txt b/tests/baselines/reference/for-of39.errors.txt index ed73bcf056a..98987fdd2c1 100644 --- a/tests/baselines/reference/for-of39.errors.txt +++ b/tests/baselines/reference/for-of39.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,19): error TS2345: Argument of type '([string, boolean] | [string, number])[]' is not assignable to parameter of type 'Iterable<[string, boolean]>'. +tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,19): error TS2345: Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'Iterable<[string, boolean]>'. Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator<[string, boolean] | [string, number]>' is not assignable to type '() => Iterator<[string, boolean]>'. - Type 'IterableIterator<[string, boolean] | [string, number]>' is not assignable to type 'Iterator<[string, boolean]>'. + Type '() => IterableIterator<[string, number] | [string, true]>' is not assignable to type '() => Iterator<[string, boolean]>'. + Type 'IterableIterator<[string, number] | [string, true]>' is not assignable to type 'Iterator<[string, boolean]>'. Types of property 'next' are incompatible. - Type '(value?: any) => IteratorResult<[string, boolean] | [string, number]>' is not assignable to type '(value?: any) => IteratorResult<[string, boolean]>'. - Type 'IteratorResult<[string, boolean] | [string, number]>' is not assignable to type 'IteratorResult<[string, boolean]>'. - Type '[string, boolean] | [string, number]' is not assignable to type '[string, boolean]'. + Type '(value?: any) => IteratorResult<[string, number] | [string, true]>' is not assignable to type '(value?: any) => IteratorResult<[string, boolean]>'. + Type 'IteratorResult<[string, number] | [string, true]>' is not assignable to type 'IteratorResult<[string, boolean]>'. + Type '[string, number] | [string, true]' is not assignable to type '[string, boolean]'. Type '[string, number]' is not assignable to type '[string, boolean]'. Type 'number' is not assignable to type 'boolean'. @@ -13,14 +13,14 @@ tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,19): error TS2345: Ar ==== tests/cases/conformance/es6/for-ofStatements/for-of39.ts (1 errors) ==== var map = new Map([["", true], ["", 0]]); ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '([string, boolean] | [string, number])[]' is not assignable to parameter of type 'Iterable<[string, boolean]>'. +!!! error TS2345: Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'Iterable<[string, boolean]>'. !!! error TS2345: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2345: Type '() => IterableIterator<[string, boolean] | [string, number]>' is not assignable to type '() => Iterator<[string, boolean]>'. -!!! error TS2345: Type 'IterableIterator<[string, boolean] | [string, number]>' is not assignable to type 'Iterator<[string, boolean]>'. +!!! error TS2345: Type '() => IterableIterator<[string, number] | [string, true]>' is not assignable to type '() => Iterator<[string, boolean]>'. +!!! error TS2345: Type 'IterableIterator<[string, number] | [string, true]>' is not assignable to type 'Iterator<[string, boolean]>'. !!! error TS2345: Types of property 'next' are incompatible. -!!! error TS2345: Type '(value?: any) => IteratorResult<[string, boolean] | [string, number]>' is not assignable to type '(value?: any) => IteratorResult<[string, boolean]>'. -!!! error TS2345: Type 'IteratorResult<[string, boolean] | [string, number]>' is not assignable to type 'IteratorResult<[string, boolean]>'. -!!! error TS2345: Type '[string, boolean] | [string, number]' is not assignable to type '[string, boolean]'. +!!! error TS2345: Type '(value?: any) => IteratorResult<[string, number] | [string, true]>' is not assignable to type '(value?: any) => IteratorResult<[string, boolean]>'. +!!! error TS2345: Type 'IteratorResult<[string, number] | [string, true]>' is not assignable to type 'IteratorResult<[string, boolean]>'. +!!! error TS2345: Type '[string, number] | [string, true]' is not assignable to type '[string, boolean]'. !!! error TS2345: Type '[string, number]' is not assignable to type '[string, boolean]'. !!! error TS2345: Type 'number' is not assignable to type 'boolean'. for (var [k, v] of map) { diff --git a/tests/baselines/reference/for-of40.types b/tests/baselines/reference/for-of40.types index e29d6170021..4c690ed9ce7 100644 --- a/tests/baselines/reference/for-of40.types +++ b/tests/baselines/reference/for-of40.types @@ -3,8 +3,8 @@ var map = new Map([["", true]]); >map : Map >new Map([["", true]]) : Map >Map : MapConstructor ->[["", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/for-of44.types b/tests/baselines/reference/for-of44.types index adac4b418e0..64be808f868 100644 --- a/tests/baselines/reference/for-of44.types +++ b/tests/baselines/reference/for-of44.types @@ -1,11 +1,11 @@ === tests/cases/conformance/es6/for-ofStatements/for-of44.ts === var array: [number, string | boolean | symbol][] = [[0, ""], [0, true], [1, Symbol()]] >array : [number, string | boolean | symbol][] ->[[0, ""], [0, true], [1, Symbol()]] : ([number, string] | [number, boolean] | [number, symbol])[] +>[[0, ""], [0, true], [1, Symbol()]] : ([number, string] | [number, true] | [number, symbol])[] >[0, ""] : [number, string] >0 : 0 >"" : "" ->[0, true] : [number, boolean] +>[0, true] : [number, true] >0 : 0 >true : true >[1, Symbol()] : [number, symbol] diff --git a/tests/baselines/reference/for-of45.types b/tests/baselines/reference/for-of45.types index 088346eef9c..6e6a0a11bf4 100644 --- a/tests/baselines/reference/for-of45.types +++ b/tests/baselines/reference/for-of45.types @@ -7,8 +7,8 @@ var map = new Map([["", true]]); >map : Map >new Map([["", true]]) : Map >Map : MapConstructor ->[["", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/for-of46.types b/tests/baselines/reference/for-of46.types index 15907dae62e..73a91f63b66 100644 --- a/tests/baselines/reference/for-of46.types +++ b/tests/baselines/reference/for-of46.types @@ -7,8 +7,8 @@ var map = new Map([["", true]]); >map : Map >new Map([["", true]]) : Map >Map : MapConstructor ->[["", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/for-of49.types b/tests/baselines/reference/for-of49.types index 185899f8b83..bed54d205ea 100644 --- a/tests/baselines/reference/for-of49.types +++ b/tests/baselines/reference/for-of49.types @@ -7,8 +7,8 @@ var map = new Map([["", true]]); >map : Map >new Map([["", true]]) : Map >Map : MapConstructor ->[["", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/for-of50.types b/tests/baselines/reference/for-of50.types index df082ad0e59..8da06665711 100644 --- a/tests/baselines/reference/for-of50.types +++ b/tests/baselines/reference/for-of50.types @@ -3,8 +3,8 @@ var map = new Map([["", true]]); >map : Map >new Map([["", true]]) : Map >Map : MapConstructor ->[["", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true diff --git a/tests/baselines/reference/functionOverloads39.types b/tests/baselines/reference/functionOverloads39.types index e6f2adf0b9b..bf4a6ec5ae9 100644 --- a/tests/baselines/reference/functionOverloads39.types +++ b/tests/baselines/reference/functionOverloads39.types @@ -19,8 +19,8 @@ var x = foo([{a:true}]); >x : number >foo([{a:true}]) : number >foo : { (bar: { a: number; }[]): string; (bar: { a: boolean; }[]): number; } ->[{a:true}] : { a: boolean; }[] ->{a:true} : { a: boolean; } ->a : boolean +>[{a:true}] : { a: true; }[] +>{a:true} : { a: true; } +>a : true >true : true diff --git a/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.types b/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.types index 15be2088615..06f7a29f27c 100644 --- a/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.types +++ b/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.types @@ -64,7 +64,7 @@ _.all([true], _.identity); >_.all : (list: T[], iterator?: Underscore.Iterator, context?: any) => boolean >_ : Underscore.Static >all : (list: T[], iterator?: Underscore.Iterator, context?: any) => boolean ->[true] : boolean[] +>[true] : true[] >true : true >_.identity : (value: T) => T >_ : Underscore.Static diff --git a/tests/baselines/reference/genericTypeArgumentInference1.types b/tests/baselines/reference/genericTypeArgumentInference1.types index 1223fdb9d5c..9eb80c4135e 100644 --- a/tests/baselines/reference/genericTypeArgumentInference1.types +++ b/tests/baselines/reference/genericTypeArgumentInference1.types @@ -62,7 +62,7 @@ var r2 = _.all([true], _.identity); >_.all : (list: T[], iterator?: Underscore.Iterator, context?: any) => T >_ : Underscore.Static >all : (list: T[], iterator?: Underscore.Iterator, context?: any) => T ->[true] : boolean[] +>[true] : true[] >true : true >_.identity : (value: T) => T >_ : Underscore.Static diff --git a/tests/baselines/reference/getAndSetAsMemberNames.types b/tests/baselines/reference/getAndSetAsMemberNames.types index d84709ed473..00c3db97b8c 100644 --- a/tests/baselines/reference/getAndSetAsMemberNames.types +++ b/tests/baselines/reference/getAndSetAsMemberNames.types @@ -40,7 +40,7 @@ class C5 { public set: () => boolean = function () { return true; }; >set : () => boolean ->function () { return true; } : () => boolean +>function () { return true; } : () => true >true : true get (): boolean { return true; } diff --git a/tests/baselines/reference/getterSetterNonAccessor.types b/tests/baselines/reference/getterSetterNonAccessor.types index 57613d41107..7253dcc07e6 100644 --- a/tests/baselines/reference/getterSetterNonAccessor.types +++ b/tests/baselines/reference/getterSetterNonAccessor.types @@ -16,8 +16,8 @@ Object.defineProperty({}, "0", ({ >"0" : "0" >({ get: getFunc, set: setFunc, configurable: true }) : PropertyDescriptor >PropertyDescriptor : PropertyDescriptor ->({ get: getFunc, set: setFunc, configurable: true }) : { get: () => any; set: (v: any) => void; configurable: boolean; } ->{ get: getFunc, set: setFunc, configurable: true } : { get: () => any; set: (v: any) => void; configurable: boolean; } +>({ get: getFunc, set: setFunc, configurable: true }) : { get: () => any; set: (v: any) => void; configurable: true; } +>{ get: getFunc, set: setFunc, configurable: true } : { get: () => any; set: (v: any) => void; configurable: true; } get: getFunc, >get : () => any @@ -28,7 +28,7 @@ Object.defineProperty({}, "0", ({ >setFunc : (v: any) => void configurable: true ->configurable : boolean +>configurable : true >true : true })); diff --git a/tests/baselines/reference/indexerWithTuple.types b/tests/baselines/reference/indexerWithTuple.types index 3a046bdde47..8a14fa9816e 100644 --- a/tests/baselines/reference/indexerWithTuple.types +++ b/tests/baselines/reference/indexerWithTuple.types @@ -21,7 +21,7 @@ var unionTuple1: [number, string| number] = [10, "foo"]; var unionTuple2: [boolean, string| number] = [true, "foo"]; >unionTuple2 : [boolean, string | number] ->[true, "foo"] : [boolean, string] +>[true, "foo"] : [true, string] >true : true >"foo" : "foo" diff --git a/tests/baselines/reference/interfaceContextualType.types b/tests/baselines/reference/interfaceContextualType.types index 4866ca77d1f..78fcb6a999d 100644 --- a/tests/baselines/reference/interfaceContextualType.types +++ b/tests/baselines/reference/interfaceContextualType.types @@ -34,30 +34,30 @@ class Bug { >{} : {} this.values['comments'] = { italic: true }; ->this.values['comments'] = { italic: true } : { italic: boolean; } +>this.values['comments'] = { italic: true } : { italic: true; } >this.values['comments'] : IOptions >this.values : IMap >this : this >values : IMap >'comments' : "comments" ->{ italic: true } : { italic: boolean; } ->italic : boolean +>{ italic: true } : { italic: true; } +>italic : true >true : true } shouldBeOK() { >shouldBeOK : () => void this.values = { ->this.values = { comments: { italic: true } } : { comments: { italic: boolean; }; } +>this.values = { comments: { italic: true } } : { comments: { italic: true; }; } >this.values : IMap >this : this >values : IMap ->{ comments: { italic: true } } : { comments: { italic: boolean; }; } +>{ comments: { italic: true } } : { comments: { italic: true; }; } comments: { italic: true } ->comments : { italic: boolean; } ->{ italic: true } : { italic: boolean; } ->italic : boolean +>comments : { italic: true; } +>{ italic: true } : { italic: true; } +>italic : true >true : true }; diff --git a/tests/baselines/reference/interfaceWithPropertyOfEveryType.types b/tests/baselines/reference/interfaceWithPropertyOfEveryType.types index 7817c1815ce..f31b280c9ec 100644 --- a/tests/baselines/reference/interfaceWithPropertyOfEveryType.types +++ b/tests/baselines/reference/interfaceWithPropertyOfEveryType.types @@ -80,7 +80,7 @@ interface Foo { var a: Foo = { >a : Foo >Foo : Foo ->{ a: 1, b: '', c: true, d: {}, e: null , f: [1], g: {}, h: (x: number) => 1, i: (x: T) => x, j: null, k: new C(), l: f1, m: M, n: {}, o: E.A} : { a: number; b: string; c: boolean; d: {}; e: null; f: number[]; g: {}; h: (x: number) => number; i: (x: T) => T; j: Foo; k: C; l: () => void; m: typeof M; n: {}; o: E; } +>{ a: 1, b: '', c: true, d: {}, e: null , f: [1], g: {}, h: (x: number) => 1, i: (x: T) => x, j: null, k: new C(), l: f1, m: M, n: {}, o: E.A} : { a: number; b: string; c: true; d: {}; e: null; f: number[]; g: {}; h: (x: number) => number; i: (x: T) => T; j: Foo; k: C; l: () => void; m: typeof M; n: {}; o: E; } a: 1, >a : number @@ -91,7 +91,7 @@ var a: Foo = { >'' : "" c: true, ->c : boolean +>c : true >true : true d: {}, diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index abb1bca93fc..8ebac188248 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -245,8 +245,8 @@ function f3() { >assignBoxified(b, { c: false }) : void >assignBoxified : (obj: Boxified, values: T) => void >b : { a: Box; b: Box; c: Box; } ->{ c: false } : { c: boolean; } ->c : boolean +>{ c: false } : { c: false; } +>c : false >false : false } diff --git a/tests/baselines/reference/iterableArrayPattern23.types b/tests/baselines/reference/iterableArrayPattern23.types index 7f424fb1582..83345816b91 100644 --- a/tests/baselines/reference/iterableArrayPattern23.types +++ b/tests/baselines/reference/iterableArrayPattern23.types @@ -4,11 +4,11 @@ var a: string, b: boolean; >b : boolean [a, b] = { 0: "", 1: true }; ->[a, b] = { 0: "", 1: true } : { 0: string; 1: boolean; } +>[a, b] = { 0: "", 1: true } : { 0: string; 1: true; } >[a, b] : [string, boolean] >a : string >b : boolean ->{ 0: "", 1: true } : { 0: string; 1: boolean; } +>{ 0: "", 1: true } : { 0: string; 1: true; } >"" : "" >true : true diff --git a/tests/baselines/reference/iterableArrayPattern24.types b/tests/baselines/reference/iterableArrayPattern24.types index 1c74e86ed71..3d8824ba98e 100644 --- a/tests/baselines/reference/iterableArrayPattern24.types +++ b/tests/baselines/reference/iterableArrayPattern24.types @@ -4,12 +4,12 @@ var a: string, b: boolean[]; >b : boolean[] [a, ...b] = { 0: "", 1: true }; ->[a, ...b] = { 0: "", 1: true } : { 0: string; 1: boolean; } +>[a, ...b] = { 0: "", 1: true } : { 0: string; 1: true; } >[a, ...b] : (string | boolean)[] >a : string >...b : boolean >b : boolean[] ->{ 0: "", 1: true } : { 0: string; 1: boolean; } +>{ 0: "", 1: true } : { 0: string; 1: true; } >"" : "" >true : true diff --git a/tests/baselines/reference/iterableArrayPattern29.types b/tests/baselines/reference/iterableArrayPattern29.types index a213778d412..faa75272904 100644 --- a/tests/baselines/reference/iterableArrayPattern29.types +++ b/tests/baselines/reference/iterableArrayPattern29.types @@ -12,11 +12,11 @@ takeFirstTwoEntries(...new Map([["", true], ["hello", true]])); >...new Map([["", true], ["hello", true]]) : [string, boolean] >new Map([["", true], ["hello", true]]) : Map >Map : MapConstructor ->[["", true], ["hello", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true], ["hello", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true ->["hello", true] : [string, boolean] +>["hello", true] : [string, true] >"hello" : "hello" >true : true diff --git a/tests/baselines/reference/iterableArrayPattern30.types b/tests/baselines/reference/iterableArrayPattern30.types index 0a4003afa1d..1abdba039ed 100644 --- a/tests/baselines/reference/iterableArrayPattern30.types +++ b/tests/baselines/reference/iterableArrayPattern30.types @@ -6,11 +6,11 @@ const [[k1, v1], [k2, v2]] = new Map([["", true], ["hello", true]]) >v2 : boolean >new Map([["", true], ["hello", true]]) : Map >Map : MapConstructor ->[["", true], ["hello", true]] : [string, boolean][] ->["", true] : [string, boolean] +>[["", true], ["hello", true]] : [string, true][] +>["", true] : [string, true] >"" : "" >true : true ->["hello", true] : [string, boolean] +>["hello", true] : [string, true] >"hello" : "hello" >true : true diff --git a/tests/baselines/reference/jsdocParamTagTypeLiteral.types b/tests/baselines/reference/jsdocParamTagTypeLiteral.types index 983c5927921..c705647c9d2 100644 --- a/tests/baselines/reference/jsdocParamTagTypeLiteral.types +++ b/tests/baselines/reference/jsdocParamTagTypeLiteral.types @@ -149,20 +149,20 @@ function foo5(opts5) { foo5([{ help: "help", what: { a: 'a', bad: [{ idea: 'idea', oh: false }] }, unnest: 1 }]); >foo5([{ help: "help", what: { a: 'a', bad: [{ idea: 'idea', oh: false }] }, unnest: 1 }]) : void >foo5 : (opts5: { help: string; what: { a: string; bad: { idea: string; oh: boolean; }[]; }; unnest: number; }[]) => void ->[{ help: "help", what: { a: 'a', bad: [{ idea: 'idea', oh: false }] }, unnest: 1 }] : { help: string; what: { a: string; bad: { idea: string; oh: boolean; }[]; }; unnest: number; }[] ->{ help: "help", what: { a: 'a', bad: [{ idea: 'idea', oh: false }] }, unnest: 1 } : { help: string; what: { a: string; bad: { idea: string; oh: boolean; }[]; }; unnest: number; } +>[{ help: "help", what: { a: 'a', bad: [{ idea: 'idea', oh: false }] }, unnest: 1 }] : { help: string; what: { a: string; bad: { idea: string; oh: false; }[]; }; unnest: number; }[] +>{ help: "help", what: { a: 'a', bad: [{ idea: 'idea', oh: false }] }, unnest: 1 } : { help: string; what: { a: string; bad: { idea: string; oh: false; }[]; }; unnest: number; } >help : string >"help" : "help" ->what : { a: string; bad: { idea: string; oh: boolean; }[]; } ->{ a: 'a', bad: [{ idea: 'idea', oh: false }] } : { a: string; bad: { idea: string; oh: boolean; }[]; } +>what : { a: string; bad: { idea: string; oh: false; }[]; } +>{ a: 'a', bad: [{ idea: 'idea', oh: false }] } : { a: string; bad: { idea: string; oh: false; }[]; } >a : string >'a' : "a" ->bad : { idea: string; oh: boolean; }[] ->[{ idea: 'idea', oh: false }] : { idea: string; oh: boolean; }[] ->{ idea: 'idea', oh: false } : { idea: string; oh: boolean; } +>bad : { idea: string; oh: false; }[] +>[{ idea: 'idea', oh: false }] : { idea: string; oh: false; }[] +>{ idea: 'idea', oh: false } : { idea: string; oh: false; } >idea : string >'idea' : "idea" ->oh : boolean +>oh : false >false : false >unnest : number >1 : 1 diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index d60245e183f..e9449477d20 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -572,14 +572,14 @@ function f31(key: K) { const shape: Shape = { name: "foo", width: 5, height: 10, visible: true }; >shape : Shape >Shape : Shape ->{ name: "foo", width: 5, height: 10, visible: true } : { name: string; width: number; height: number; visible: boolean; } +>{ name: "foo", width: 5, height: 10, visible: true } : { name: string; width: number; height: number; visible: true; } >name : string >"foo" : "foo" >width : number >5 : 5 >height : number >10 : 10 ->visible : boolean +>visible : true >true : true return shape[key]; // Shape[K] @@ -597,14 +597,14 @@ function f32(key: K) { const shape: Shape = { name: "foo", width: 5, height: 10, visible: true }; >shape : Shape >Shape : Shape ->{ name: "foo", width: 5, height: 10, visible: true } : { name: string; width: number; height: number; visible: boolean; } +>{ name: "foo", width: 5, height: 10, visible: true } : { name: string; width: number; height: number; visible: true; } >name : string >"foo" : "foo" >width : number >5 : 5 >height : number >10 : 10 ->visible : boolean +>visible : true >true : true return shape[key]; // Shape[K] @@ -952,8 +952,8 @@ function f71(func: (x: T, y: U) => Partial) { >1 : 1 >b : string >"hello" : "hello" ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true x.a; // number | undefined @@ -999,8 +999,8 @@ function f72(func: (x: T, y: U, k: K) => (T & >1 : 1 >b : string >"hello" : "hello" ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true >'a' : "a" @@ -1013,8 +1013,8 @@ function f72(func: (x: T, y: U, k: K) => (T & >1 : 1 >b : string >"hello" : "hello" ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true >'b' : "b" @@ -1027,8 +1027,8 @@ function f72(func: (x: T, y: U, k: K) => (T & >1 : 1 >b : string >"hello" : "hello" ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true >'c' : "c" } @@ -1060,8 +1060,8 @@ function f73(func: (x: T, y: U, k: K) => (T & U)[ >1 : 1 >b : string >"hello" : "hello" ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true >'a' : "a" @@ -1074,8 +1074,8 @@ function f73(func: (x: T, y: U, k: K) => (T & U)[ >1 : 1 >b : string >"hello" : "hello" ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true >'b' : "b" @@ -1088,8 +1088,8 @@ function f73(func: (x: T, y: U, k: K) => (T & U)[ >1 : 1 >b : string >"hello" : "hello" ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true >'c' : "c" } @@ -1121,10 +1121,10 @@ function f74(func: (x: T, y: U, k: K) => (T | U)[ >1 : 1 >b : string >"hello" : "hello" ->{ a: 2, b: true } : { a: number; b: boolean; } +>{ a: 2, b: true } : { a: number; b: true; } >a : number >2 : 2 ->b : boolean +>b : true >true : true >'a' : "a" @@ -1137,10 +1137,10 @@ function f74(func: (x: T, y: U, k: K) => (T | U)[ >1 : 1 >b : string >"hello" : "hello" ->{ a: 2, b: true } : { a: number; b: boolean; } +>{ a: 2, b: true } : { a: number; b: true; } >a : number >2 : 2 ->b : boolean +>b : true >true : true >'b' : "b" } diff --git a/tests/baselines/reference/literalTypes2.types b/tests/baselines/reference/literalTypes2.types index 85775fb06e3..429a1457c4e 100644 --- a/tests/baselines/reference/literalTypes2.types +++ b/tests/baselines/reference/literalTypes2.types @@ -501,8 +501,8 @@ function f6() { >0 : 0 >x3 : string >"foo" : "foo" ->{ x1: false, x2: 1, x3: "bar" } : { x1?: boolean; x2?: number; x3?: string; } ->x1 : boolean +>{ x1: false, x2: 1, x3: "bar" } : { x1?: false; x2?: number; x3?: string; } +>x1 : false >false : false >x2 : number >1 : 1 diff --git a/tests/baselines/reference/mappedTypeErrors.types b/tests/baselines/reference/mappedTypeErrors.types index 73ecb657dff..ab0ae55a0e1 100644 --- a/tests/baselines/reference/mappedTypeErrors.types +++ b/tests/baselines/reference/mappedTypeErrors.types @@ -613,10 +613,10 @@ type O = {x: number, y: boolean}; let o: O = {x: 5, y: false}; >o : O >O : O ->{x: 5, y: false} : { x: number; y: boolean; } +>{x: 5, y: false} : { x: number; y: false; } >x : number >5 : 5 ->y : boolean +>y : false >false : false let f: Foo2 = { diff --git a/tests/baselines/reference/objectLiteralNormalization.errors.txt b/tests/baselines/reference/objectLiteralNormalization.errors.txt index 46610d8d3da..6bdc9b955e3 100644 --- a/tests/baselines/reference/objectLiteralNormalization.errors.txt +++ b/tests/baselines/reference/objectLiteralNormalization.errors.txt @@ -4,9 +4,9 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(8,1): error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. Type '{ b: string; }' is not assignable to type '{ a: number; b: string; c: boolean; }'. Property 'a' is missing in type '{ b: string; }'. -tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(9,1): error TS2322: Type '{ c: boolean; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. - Type '{ c: boolean; }' is not assignable to type '{ a: number; b: string; c: boolean; }'. - Property 'a' is missing in type '{ c: boolean; }'. +tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(9,1): error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. + Type '{ c: true; }' is not assignable to type '{ a: number; b: string; c: boolean; }'. + Property 'a' is missing in type '{ c: true; }'. tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(17,1): error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'. Types of property 'a' are incompatible. @@ -36,9 +36,9 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts !!! error TS2322: Property 'a' is missing in type '{ b: string; }'. a1 = { c: true }; // Error ~~ -!!! error TS2322: Type '{ c: boolean; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. -!!! error TS2322: Type '{ c: boolean; }' is not assignable to type '{ a: number; b: string; c: boolean; }'. -!!! error TS2322: Property 'a' is missing in type '{ c: boolean; }'. +!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. +!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b: string; c: boolean; }'. +!!! error TS2322: Property 'a' is missing in type '{ c: true; }'. let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0]; a2.a; // string | number | undefined diff --git a/tests/baselines/reference/objectLiteralNormalization.types b/tests/baselines/reference/objectLiteralNormalization.types index 5c1d1de76fa..63cdf86b5b9 100644 --- a/tests/baselines/reference/objectLiteralNormalization.types +++ b/tests/baselines/reference/objectLiteralNormalization.types @@ -60,10 +60,10 @@ a1 = { b: "y" }; // Error >"y" : "y" a1 = { c: true }; // Error ->a1 = { c: true } : { c: boolean; } +>a1 = { c: true } : { c: true; } >a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } ->{ c: true } : { c: boolean; } ->c : boolean +>{ c: true } : { c: true; } +>c : true >true : true let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0]; diff --git a/tests/baselines/reference/objectLiteralParameterResolution.types b/tests/baselines/reference/objectLiteralParameterResolution.types index 72dded236a1..56d61163eca 100644 --- a/tests/baselines/reference/objectLiteralParameterResolution.types +++ b/tests/baselines/reference/objectLiteralParameterResolution.types @@ -29,7 +29,7 @@ var s = $.extend({ >$.extend : { (target: T, ...objs: any[]): T; (deep: boolean, target: T, ...objs: any[]): T; } >$ : Foo >extend : { (target: T, ...objs: any[]): T; (deep: boolean, target: T, ...objs: any[]): T; } ->{ type: "GET" , data: "data" , success: wrapSuccessCallback(requestContext, callback) , error: wrapErrorCallback(requestContext, errorCallback) , dataType: "json" , converters: { "text json": "" }, traditional: true , timeout: 12, } : { type: string; data: string; success: any; error: any; dataType: string; converters: { "text json": string; }; traditional: boolean; timeout: number; } +>{ type: "GET" , data: "data" , success: wrapSuccessCallback(requestContext, callback) , error: wrapErrorCallback(requestContext, errorCallback) , dataType: "json" , converters: { "text json": "" }, traditional: true , timeout: 12, } : { type: string; data: string; success: any; error: any; dataType: string; converters: { "text json": string; }; traditional: true; timeout: number; } type: "GET" , >type : string @@ -63,7 +63,7 @@ var s = $.extend({ >"" : "" traditional: true , ->traditional : boolean +>traditional : true >true : true timeout: 12, diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index 1f87ed4930d..3270cdfe8f0 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -31,9 +31,9 @@ let addAfter: { a: number, b: string, c: boolean } = >c : boolean { ...o, c: false } ->{ ...o, c: false } : { c: boolean; a: number; b: string; } +>{ ...o, c: false } : { c: false; a: number; b: string; } >o : { a: number; b: string; } ->c : boolean +>c : false >false : false let addBefore: { a: number, b: string, c: boolean } = @@ -43,8 +43,8 @@ let addBefore: { a: number, b: string, c: boolean } = >c : boolean { c: false, ...o } ->{ c: false, ...o } : { a: number; b: string; c: boolean; } ->c : boolean +>{ c: false, ...o } : { a: number; b: string; c: false; } +>c : false >false : false >o : { a: number; b: string; } @@ -78,12 +78,12 @@ let nested: { a: number, b: boolean, c: string } = >c : string { ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } ->{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } : { c: string; b: boolean; a: number; } ->{ a: 3, ...{ b: false, c: 'overriden' } } : { b: boolean; c: string; a: number; } +>{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } : { c: string; b: false; a: number; } +>{ a: 3, ...{ b: false, c: 'overriden' } } : { b: false; c: string; a: number; } >a : number >3 : 3 ->{ b: false, c: 'overriden' } : { b: boolean; c: string; } ->b : boolean +>{ b: false, c: 'overriden' } : { b: false; c: string; } +>b : false >false : false >c : string >'overriden' : "overriden" @@ -148,12 +148,12 @@ let combinedNested: { a: number, b: boolean, c: string, d: string } = >d : string { ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } ->{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } : { a: number; d: string; b: boolean; c: string; } ->{ a: 4, ...{ b: false, c: 'overriden' } } : { b: boolean; c: string; a: number; } +>{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } : { a: number; d: string; b: false; c: string; } +>{ a: 4, ...{ b: false, c: 'overriden' } } : { b: false; c: string; a: number; } >a : number >4 : 4 ->{ b: false, c: 'overriden' } : { b: boolean; c: string; } ->b : boolean +>{ b: false, c: 'overriden' } : { b: false; c: string; } +>b : false >false : false >c : string >'overriden' : "overriden" @@ -172,12 +172,12 @@ let combinedNestedChangeType: { a: number, b: boolean, c: number } = >c : number { ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } ->{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } : { c: number; b: boolean; a: number; } ->{ a: 1, ...{ b: false, c: 'overriden' } } : { b: boolean; c: string; a: number; } +>{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } : { c: number; b: false; a: number; } +>{ a: 1, ...{ b: false, c: 'overriden' } } : { b: false; c: string; a: number; } >a : number >1 : 1 ->{ b: false, c: 'overriden' } : { b: boolean; c: string; } ->b : boolean +>{ b: false, c: 'overriden' } : { b: false; c: string; } +>b : false >false : false >c : string >'overriden' : "overriden" diff --git a/tests/baselines/reference/objectSpreadNegative.types b/tests/baselines/reference/objectSpreadNegative.types index 5c3abb041f8..b324f822e03 100644 --- a/tests/baselines/reference/objectSpreadNegative.types +++ b/tests/baselines/reference/objectSpreadNegative.types @@ -278,10 +278,10 @@ let exclusive: { id: string, a: number, b: string, c: string, d: boolean } = >1 : 1 >b : string >'yes' : "yes" ->{ c: 'no', d: false } : { c: string; d: boolean; } +>{ c: 'no', d: false } : { c: string; d: false; } >c : string >'no' : "no" ->d : boolean +>d : false >false : false let overlap: { id: string, a: number, b: string } = @@ -327,10 +327,10 @@ let overwriteId: { id: string, a: number, c: number, d: string } = f({ a: 1, id: true }, { c: 1, d: 'no' }) >f({ a: 1, id: true }, { c: 1, d: 'no' }) : any >f : (t: T, u: U) => any ->{ a: 1, id: true } : { a: number; id: boolean; } +>{ a: 1, id: true } : { a: number; id: true; } >a : number >1 : 1 ->id : boolean +>id : true >true : true >{ c: 1, d: 'no' } : { c: number; d: string; } >c : number diff --git a/tests/baselines/reference/optionalBindingParameters1.types b/tests/baselines/reference/optionalBindingParameters1.types index be3f4e25d01..74b25532513 100644 --- a/tests/baselines/reference/optionalBindingParameters1.types +++ b/tests/baselines/reference/optionalBindingParameters1.types @@ -10,7 +10,7 @@ function foo([x,y,z]?: [string, number, boolean]) { foo(["", 0, false]); >foo(["", 0, false]) : void >foo : ([x, y, z]?: [string, number, boolean]) => void ->["", 0, false] : [string, number, boolean] +>["", 0, false] : [string, number, false] >"" : "" >0 : 0 >false : false diff --git a/tests/baselines/reference/optionalBindingParameters2.types b/tests/baselines/reference/optionalBindingParameters2.types index 39b7744e2a1..79fb6ef7a58 100644 --- a/tests/baselines/reference/optionalBindingParameters2.types +++ b/tests/baselines/reference/optionalBindingParameters2.types @@ -13,12 +13,12 @@ function foo({ x, y, z }?: { x: string; y: number; z: boolean }) { foo({ x: "", y: 0, z: false }); >foo({ x: "", y: 0, z: false }) : void >foo : ({ x, y, z }?: { x: string; y: number; z: boolean; }) => void ->{ x: "", y: 0, z: false } : { x: string; y: number; z: boolean; } +>{ x: "", y: 0, z: false } : { x: string; y: number; z: false; } >x : string >"" : "" >y : number >0 : 0 ->z : boolean +>z : false >false : false foo({ x: false, y: 0, z: "" }); diff --git a/tests/baselines/reference/optionalBindingParametersInOverloads1.types b/tests/baselines/reference/optionalBindingParametersInOverloads1.types index ffb128aad53..01d1756a6ac 100644 --- a/tests/baselines/reference/optionalBindingParametersInOverloads1.types +++ b/tests/baselines/reference/optionalBindingParametersInOverloads1.types @@ -14,7 +14,7 @@ function foo(...rest: any[]) { foo(["", 0, false]); >foo(["", 0, false]) : any >foo : ([x, y, z]?: [string, number, boolean]) => any ->["", 0, false] : [string, number, boolean] +>["", 0, false] : [string, number, false] >"" : "" >0 : 0 >false : false diff --git a/tests/baselines/reference/optionalBindingParametersInOverloads2.types b/tests/baselines/reference/optionalBindingParametersInOverloads2.types index 4567103e9a7..acf4afe352f 100644 --- a/tests/baselines/reference/optionalBindingParametersInOverloads2.types +++ b/tests/baselines/reference/optionalBindingParametersInOverloads2.types @@ -17,12 +17,12 @@ function foo(...rest: any[]) { foo({ x: "", y: 0, z: false }); >foo({ x: "", y: 0, z: false }) : any >foo : ({ x, y, z }?: { x: string; y: number; z: boolean; }) => any ->{ x: "", y: 0, z: false } : { x: string; y: number; z: boolean; } +>{ x: "", y: 0, z: false } : { x: string; y: number; z: false; } >x : string >"" : "" >y : number >0 : 0 ->z : boolean +>z : false >false : false foo({ x: false, y: 0, z: "" }); diff --git a/tests/baselines/reference/overloadResolutionTest1.types b/tests/baselines/reference/overloadResolutionTest1.types index 72522679b6b..0268a4d17f6 100644 --- a/tests/baselines/reference/overloadResolutionTest1.types +++ b/tests/baselines/reference/overloadResolutionTest1.types @@ -19,9 +19,9 @@ var x1 = foo([{a:true}]); // works >x1 : number >foo([{a:true}]) : number >foo : { (bar: { a: number; }[]): string; (bar: { a: boolean; }[]): number; } ->[{a:true}] : { a: boolean; }[] ->{a:true} : { a: boolean; } ->a : boolean +>[{a:true}] : { a: true; }[] +>{a:true} : { a: true; } +>a : true >true : true var x11 = foo([{a:0}]); // works @@ -81,8 +81,8 @@ var x3 = foo2({a:true}); // works >x3 : number >foo2({a:true}) : number >foo2 : { (bar: { a: number; }): string; (bar: { a: boolean; }): number; } ->{a:true} : { a: boolean; } ->a : boolean +>{a:true} : { a: true; } +>a : true >true : true var x4 = foo2({a:"s"}); // error diff --git a/tests/baselines/reference/parserUsingConstructorAsIdentifier.types b/tests/baselines/reference/parserUsingConstructorAsIdentifier.types index fabdadd2851..fa5e60a12b8 100644 --- a/tests/baselines/reference/parserUsingConstructorAsIdentifier.types +++ b/tests/baselines/reference/parserUsingConstructorAsIdentifier.types @@ -97,14 +97,14 @@ >constructor : any >prototype : any >"constructor" : "constructor" ->{ value: constructor, writable: true, configurable: true, enumerable: true } : { value: any; writable: boolean; configurable: boolean; enumerable: boolean; } +>{ value: constructor, writable: true, configurable: true, enumerable: true } : { value: any; writable: true; configurable: true; enumerable: true; } >value : any >constructor : any ->writable : boolean +>writable : true >true : true ->configurable : boolean +>configurable : true >true : true ->enumerable : boolean +>enumerable : true >true : true if (instanceMembers) { diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index 284eb887dd4..cf08fc969ea 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -1581,14 +1581,14 @@ module Harness { var metadata: IScenarioMetadata = { id: undefined, desc: this.description, pass: false, bugs: assert.bugIds }; >metadata : IScenarioMetadata >IScenarioMetadata : IScenarioMetadata ->{ id: undefined, desc: this.description, pass: false, bugs: assert.bugIds } : { id: undefined; desc: any; pass: boolean; bugs: any; } +>{ id: undefined, desc: this.description, pass: false, bugs: assert.bugIds } : { id: undefined; desc: any; pass: false; bugs: any; } >id : undefined >undefined : undefined >desc : any >this.description : any >this : any >description : any ->pass : boolean +>pass : false >false : false >bugs : any >assert.bugIds : any diff --git a/tests/baselines/reference/privacyCheckAnonymousFunctionParameter.types b/tests/baselines/reference/privacyCheckAnonymousFunctionParameter.types index 8326070daf1..0c025ceaee3 100644 --- a/tests/baselines/reference/privacyCheckAnonymousFunctionParameter.types +++ b/tests/baselines/reference/privacyCheckAnonymousFunctionParameter.types @@ -31,7 +31,7 @@ module Query { return fromDoWhile(test => { >fromDoWhile(test => { return true; }) : Iterator<{}> >fromDoWhile : (doWhile: (test: Iterator) => boolean) => Iterator ->test => { return true; } : (test: Iterator<{}>) => boolean +>test => { return true; } : (test: Iterator<{}>) => true >test : Iterator<{}> return true; diff --git a/tests/baselines/reference/symbolProperty21.errors.txt b/tests/baselines/reference/symbolProperty21.errors.txt index fa9cabc9b61..766af0659e8 100644 --- a/tests/baselines/reference/symbolProperty21.errors.txt +++ b/tests/baselines/reference/symbolProperty21.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/Symbols/symbolProperty21.ts(10,5): error TS2345: Argument of type '{ [Symbol.isConcatSpreadable]: string; [Symbol.toPrimitive]: number; [Symbol.unscopables]: boolean; }' is not assignable to parameter of type 'I'. +tests/cases/conformance/es6/Symbols/symbolProperty21.ts(10,5): error TS2345: Argument of type '{ [Symbol.isConcatSpreadable]: string; [Symbol.toPrimitive]: number; [Symbol.unscopables]: true; }' is not assignable to parameter of type 'I'. Object literal may only specify known properties, and '[Symbol.toPrimitive]' does not exist in type 'I'. @@ -14,7 +14,7 @@ tests/cases/conformance/es6/Symbols/symbolProperty21.ts(10,5): error TS2345: Arg [Symbol.isConcatSpreadable]: "", [Symbol.toPrimitive]: 0, ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ [Symbol.isConcatSpreadable]: string; [Symbol.toPrimitive]: number; [Symbol.unscopables]: boolean; }' is not assignable to parameter of type 'I'. +!!! error TS2345: Argument of type '{ [Symbol.isConcatSpreadable]: string; [Symbol.toPrimitive]: number; [Symbol.unscopables]: true; }' is not assignable to parameter of type 'I'. !!! error TS2345: Object literal may only specify known properties, and '[Symbol.toPrimitive]' does not exist in type 'I'. [Symbol.unscopables]: true }); \ No newline at end of file diff --git a/tests/baselines/reference/targetTypeArgs.types b/tests/baselines/reference/targetTypeArgs.types index 3ceda8404eb..84985316aa2 100644 --- a/tests/baselines/reference/targetTypeArgs.types +++ b/tests/baselines/reference/targetTypeArgs.types @@ -35,7 +35,7 @@ foo(function(x) { x }); >["hello"] : string[] >"hello" : "hello" >every : (callbackfn: (value: string, index: number, array: string[]) => boolean, thisArg?: any) => boolean ->function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => boolean +>function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => true >v : string >i : number >a : string[] @@ -47,7 +47,7 @@ foo(function(x) { x }); >[1] : number[] >1 : 1 >every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean ->function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => boolean +>function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => true >v : number >i : number >a : number[] @@ -59,7 +59,7 @@ foo(function(x) { x }); >[1] : number[] >1 : 1 >every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean ->function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => boolean +>function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => true >v : number >i : number >a : number[] @@ -71,7 +71,7 @@ foo(function(x) { x }); >["s"] : string[] >"s" : "s" >every : (callbackfn: (value: string, index: number, array: string[]) => boolean, thisArg?: any) => boolean ->function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => boolean +>function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => true >v : string >i : number >a : string[] diff --git a/tests/baselines/reference/tsxAttributeResolution6.types b/tests/baselines/reference/tsxAttributeResolution6.types index c5aeafa81d6..e2a908cc673 100644 --- a/tests/baselines/reference/tsxAttributeResolution6.types +++ b/tests/baselines/reference/tsxAttributeResolution6.types @@ -43,7 +43,7 @@ declare module JSX { ; > : JSX.Element >test1 : any ->n : boolean +>n : false >false : false ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution6.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution6.errors.txt index 83e100b9454..d9546c3e585 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution6.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution6.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/jsx/file.tsx(13,24): error TS2322: Type '{ editable: boolean; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes & { editable: false; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })'. - Type '{ editable: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'. - Type '{ editable: boolean; }' is not assignable to type '{ editable: true; onEdit: (newText: string) => void; }'. - Property 'onEdit' is missing in type '{ editable: boolean; }'. +tests/cases/conformance/jsx/file.tsx(13,24): error TS2322: Type '{ editable: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes & { editable: false; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })'. + Type '{ editable: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'. + Type '{ editable: true; }' is not assignable to type '{ editable: true; onEdit: (newText: string) => void; }'. + Property 'onEdit' is missing in type '{ editable: true; }'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -19,10 +19,10 @@ tests/cases/conformance/jsx/file.tsx(13,24): error TS2322: Type '{ editable: boo // Error let x = ~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ editable: boolean; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes & { editable: false; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })'. -!!! error TS2322: Type '{ editable: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'. -!!! error TS2322: Type '{ editable: boolean; }' is not assignable to type '{ editable: true; onEdit: (newText: string) => void; }'. -!!! error TS2322: Property 'onEdit' is missing in type '{ editable: boolean; }'. +!!! error TS2322: Type '{ editable: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes & { editable: false; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })'. +!!! error TS2322: Type '{ editable: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'. +!!! error TS2322: Type '{ editable: true; }' is not assignable to type '{ editable: true; onEdit: (newText: string) => void; }'. +!!! error TS2322: Property 'onEdit' is missing in type '{ editable: true; }'. const textProps: TextProps = { editable: false diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution6.types b/tests/baselines/reference/tsxSpreadAttributesResolution6.types index b45fd73f266..d5e40bdf278 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution6.types +++ b/tests/baselines/reference/tsxSpreadAttributesResolution6.types @@ -35,7 +35,7 @@ let x = >x : JSX.Element > : JSX.Element >TextComponent : typeof TextComponent ->editable : boolean +>editable : true >true : true const textProps: TextProps = { diff --git a/tests/baselines/reference/typeAliases.types b/tests/baselines/reference/typeAliases.types index 777999d65a9..6c8e897480c 100644 --- a/tests/baselines/reference/typeAliases.types +++ b/tests/baselines/reference/typeAliases.types @@ -231,7 +231,7 @@ f16(x); var y: StringAndBoolean = ["1", false]; >y : [string, boolean] >StringAndBoolean : [string, boolean] ->["1", false] : [string, boolean] +>["1", false] : [string, false] >"1" : "1" >false : false diff --git a/tests/baselines/reference/typeGuardsOnClassProperty.types b/tests/baselines/reference/typeGuardsOnClassProperty.types index e08da7f1a96..510fac963d0 100644 --- a/tests/baselines/reference/typeGuardsOnClassProperty.types +++ b/tests/baselines/reference/typeGuardsOnClassProperty.types @@ -67,14 +67,14 @@ var o: { >prop2 : string | boolean } = { ->{ prop1: "string" , prop2: true } : { prop1: string; prop2: boolean; } +>{ prop1: "string" , prop2: true } : { prop1: string; prop2: true; } prop1: "string" , >prop1 : string >"string" : "string" prop2: true ->prop2 : boolean +>prop2 : true >true : true } diff --git a/tests/baselines/reference/typeInferenceLiteralUnion.types b/tests/baselines/reference/typeInferenceLiteralUnion.types index 1561ca67d43..2c662056117 100644 --- a/tests/baselines/reference/typeInferenceLiteralUnion.types +++ b/tests/baselines/reference/typeInferenceLiteralUnion.types @@ -79,7 +79,7 @@ extentMixed = extent([new NumCoercible(10), 13, '12', true]); >extentMixed : [undefined, undefined] | [string | number | boolean | Date | NumCoercible, string | number | boolean | Date | NumCoercible] >extent([new NumCoercible(10), 13, '12', true]) : [undefined, undefined] | [string | number | boolean | Date | NumCoercible, string | number | boolean | Date | NumCoercible] >extent : (array: (string | number | boolean | Date | T)[]) => [string | number | boolean | Date | T, string | number | boolean | Date | T] | [undefined, undefined] ->[new NumCoercible(10), 13, '12', true] : (string | number | boolean | NumCoercible)[] +>[new NumCoercible(10), 13, '12', true] : (string | number | true | NumCoercible)[] >new NumCoercible(10) : NumCoercible >NumCoercible : typeof NumCoercible >10 : 10 diff --git a/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively.types b/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively.types index 29fd560a763..199609078e3 100644 --- a/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively.types +++ b/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively.types @@ -62,12 +62,12 @@ foo({ x: 1 }, { x: 1, y: '' }, { x: 2, y: '', z: true }); >1 : 1 >y : string >'' : "" ->{ x: 2, y: '', z: true } : { x: number; y: string; z: boolean; } +>{ x: 2, y: '', z: true } : { x: number; y: string; z: true; } >x : number >2 : 2 >y : string >'' : "" ->z : boolean +>z : true >true : true foo(a, b, c); @@ -82,12 +82,12 @@ foo(a, b, { foo: 1, bar: '', hm: true }); >foo : (x: T, y: U, z: V) => V >a : A >b : B ->{ foo: 1, bar: '', hm: true } : { foo: number; bar: string; hm: boolean; } +>{ foo: 1, bar: '', hm: true } : { foo: number; bar: string; hm: true; } >foo : number >1 : 1 >bar : string >'' : "" ->hm : boolean +>hm : true >true : true foo((x: number, y) => { }, (x) => { }, () => { }); diff --git a/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively2.types b/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively2.types index 01b9c91eb14..a0d7e98f69b 100644 --- a/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively2.types +++ b/tests/baselines/reference/typeParameterAsTypeParameterConstraintTransitively2.types @@ -62,12 +62,12 @@ foo({ x: 1 }, { x: 1, y: '' }, { x: 2, y: 2, z: true }); >1 : 1 >y : string >'' : "" ->{ x: 2, y: 2, z: true } : { x: number; y: number; z: boolean; } +>{ x: 2, y: 2, z: true } : { x: number; y: number; z: true; } >x : number >2 : 2 >y : number >2 : 2 ->z : boolean +>z : true >true : true foo(a, b, a); @@ -81,12 +81,12 @@ foo(a, { foo: 1, bar: '', hm: true }, b); >foo(a, { foo: 1, bar: '', hm: true }, b) : B >foo : (x: T, y: U, z: V) => V >a : A ->{ foo: 1, bar: '', hm: true } : { foo: number; bar: string; hm: boolean; } +>{ foo: 1, bar: '', hm: true } : { foo: number; bar: string; hm: true; } >foo : number >1 : 1 >bar : string >'' : "" ->hm : boolean +>hm : true >true : true >b : B diff --git a/tests/baselines/reference/underscoreTest1.types b/tests/baselines/reference/underscoreTest1.types index 8c6b2691e4e..111039994d5 100644 --- a/tests/baselines/reference/underscoreTest1.types +++ b/tests/baselines/reference/underscoreTest1.types @@ -249,7 +249,7 @@ _.any([null, 0, 'yes', false]); >_.any : { (list: T[], iterator?: Iterator_, context?: any): boolean; (list: Dictionary, iterator?: Iterator_, context?: any): boolean; } >_ : Underscore.Static >any : { (list: T[], iterator?: Iterator_, context?: any): boolean; (list: Dictionary, iterator?: Iterator_, context?: any): boolean; } ->[null, 0, 'yes', false] : (string | number | boolean)[] +>[null, 0, 'yes', false] : (string | number | false)[] >null : null >0 : 0 >'yes' : "yes" @@ -512,7 +512,7 @@ _.compact([0, 1, false, 2, '', 3]); >_.compact : (list: T[]) => T[] >_ : Underscore.Static >compact : (list: T[]) => T[] ->[0, 1, false, 2, '', 3] : (string | number | boolean)[] +>[0, 1, false, 2, '', 3] : (string | number | false)[] >0 : 0 >1 : 1 >false : false diff --git a/tests/baselines/reference/unionTypeInference.types b/tests/baselines/reference/unionTypeInference.types index a6b9f4497a5..ebaf8c01402 100644 --- a/tests/baselines/reference/unionTypeInference.types +++ b/tests/baselines/reference/unionTypeInference.types @@ -77,7 +77,7 @@ var b1 = g(["string", true]); >b1 : boolean >g(["string", true]) : boolean >g : (value: [string, T]) => T ->["string", true] : [string, boolean] +>["string", true] : [string, true] >"string" : "string" >true : true diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.types b/tests/baselines/reference/useObjectValuesAndEntries1.types index 60ad86bcb43..fccd9b0d83f 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.types +++ b/tests/baselines/reference/useObjectValuesAndEntries1.types @@ -58,8 +58,8 @@ var entries2 = Object.entries({ a: true, b: 2 }); // [string, number|boolean][ >Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor >entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } ->{ a: true, b: 2 } : { a: boolean; b: number; } ->a : boolean +>{ a: true, b: 2 } : { a: true; b: number; } +>a : true >true : true >b : number >2 : 2 @@ -70,8 +70,8 @@ var values2 = Object.values({ a: true, b: 2 }); // (number|boolean)[] >Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >Object : ObjectConstructor >values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } ->{ a: true, b: 2 } : { a: boolean; b: number; } ->a : boolean +>{ a: true, b: 2 } : { a: true; b: number; } +>a : true >true : true >b : number >2 : 2 diff --git a/tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx b/tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx new file mode 100644 index 00000000000..fd5bbb73cf6 --- /dev/null +++ b/tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx @@ -0,0 +1,28 @@ +// @strict: true +// @jsx: preserve +// @skipLibCheck: true +// @libFiles: lib.d.ts,react.d.ts +interface A { isIt: true; text: string; } +interface B { isIt: false; value: number; } +type C = A | B; +const isIt = Math.random() > 0.5; +const c: C = isIt ? { isIt, text: 'hey' } : { isIt, value: 123 }; +const cc: C = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 }; + +type ComponentProps = + | { + optionalBool: true; + mandatoryFn: () => void; + } + | { + optionalBool: false; + }; + +let Funk = (_props: ComponentProps) =>
Hello
; + +let Fail1 = () => { }} optionalBool={true} /> +let Fail2 = () => { }} optionalBool={true as true} /> +let True = true as true; +let Fail3 = () => { }} optionalBool={True} /> +let attrs2 = { optionalBool: true as true, mandatoryFn: () => { } } +let Success = () => \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsForMappedType.ts b/tests/cases/fourslash/findAllRefsForMappedType.ts index a841c7e6e46..2247b4cbf08 100644 --- a/tests/cases/fourslash/findAllRefsForMappedType.ts +++ b/tests/cases/fourslash/findAllRefsForMappedType.ts @@ -15,5 +15,5 @@ verify.referenceGroups(r1, [ ]); verify.referenceGroups(r2, [ { definition: "(property) T.a: number", ranges: [r0, r1] }, - { definition: "(property) a: boolean", ranges: [r2] } + { definition: "(property) a: true", ranges: [r2] } ]); From a33dae377170b7a0a4020da546b3e23e2c03675c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 1 Feb 2018 12:34:25 -0800 Subject: [PATCH 29/42] Rework how default vs local name selection is done to be more correct (#21526) --- src/compiler/checker.ts | 28 ++++++++- src/compiler/declarationEmitter.ts | 6 +- src/compiler/types.ts | 10 ++- src/services/signatureHelp.ts | 8 +-- src/services/utilities.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 6 +- tests/baselines/reference/api/typescript.d.ts | 6 +- ...declarationEmitTypeofDefaultExport.symbols | 4 +- .../declarationEmitTypeofDefaultExport.types | 4 +- .../defaultDeclarationEmitDefaultImport.js | 35 +++++++++++ ...efaultDeclarationEmitDefaultImport.symbols | 17 ++++++ .../defaultDeclarationEmitDefaultImport.types | 20 ++++++ .../defaultDeclarationEmitNamedCorrectly.js | 49 +++++++++++++++ ...faultDeclarationEmitNamedCorrectly.symbols | 45 ++++++++++++++ ...defaultDeclarationEmitNamedCorrectly.types | 48 +++++++++++++++ ...ltDeclarationEmitShadowedNamedCorrectly.js | 61 +++++++++++++++++++ ...larationEmitShadowedNamedCorrectly.symbols | 56 +++++++++++++++++ ...eclarationEmitShadowedNamedCorrectly.types | 60 ++++++++++++++++++ .../reference/duplicatePackage.types | 14 ++--- .../defaultDeclarationEmitDefaultImport.ts | 7 +++ .../defaultDeclarationEmitNamedCorrectly.ts | 16 +++++ ...ltDeclarationEmitShadowedNamedCorrectly.ts | 21 +++++++ 22 files changed, 494 insertions(+), 29 deletions(-) create mode 100644 tests/baselines/reference/defaultDeclarationEmitDefaultImport.js create mode 100644 tests/baselines/reference/defaultDeclarationEmitDefaultImport.symbols create mode 100644 tests/baselines/reference/defaultDeclarationEmitDefaultImport.types create mode 100644 tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.js create mode 100644 tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.symbols create mode 100644 tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.types create mode 100644 tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.js create mode 100644 tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.symbols create mode 100644 tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.types create mode 100644 tests/cases/compiler/defaultDeclarationEmitDefaultImport.ts create mode 100644 tests/cases/compiler/defaultDeclarationEmitNamedCorrectly.ts create mode 100644 tests/cases/compiler/defaultDeclarationEmitShadowedNamedCorrectly.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e75d28aa5e6..ad03dbe52e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2693,6 +2693,9 @@ namespace ts { if (flags & SymbolFormatFlags.WriteTypeParametersOrArguments) { nodeFlags |= NodeBuilderFlags.WriteTypeParametersInQualifiedName; } + if (flags & SymbolFormatFlags.UseAliasDefinedOutsideCurrentScope) { + nodeFlags |= NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; + } const builder = flags & SymbolFormatFlags.AllowAnyNodeKind ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName; return writer ? symbolToStringWorker(writer).getText() : usingSingleLineStringWriter(symbolToStringWorker); @@ -3454,7 +3457,14 @@ namespace ts { function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); const symbol = chain[index]; + + if (index === 0) { + context.flags |= NodeBuilderFlags.InInitialEntityName; + } const symbolName = getNameOfSymbolAsWritten(symbol, context); + if (index === 0) { + context.flags ^= NodeBuilderFlags.InInitialEntityName; + } const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; @@ -3471,7 +3481,13 @@ namespace ts { const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); const symbol = chain[index]; + if (index === 0) { + context.flags |= NodeBuilderFlags.InInitialEntityName; + } let symbolName = getNameOfSymbolAsWritten(symbol, context); + if (index === 0) { + context.flags ^= NodeBuilderFlags.InInitialEntityName; + } let firstChar = symbolName.charCodeAt(0); const canUsePropertyAccess = isIdentifierStart(firstChar, languageVersion); if (index === 0 || canUsePropertyAccess) { @@ -3584,6 +3600,10 @@ namespace ts { symbolStack: Symbol[] | undefined; } + function isDefaultBindingContext(location: Node) { + return location.kind === SyntaxKind.SourceFile || isAmbientModule(location); + } + /** * Gets a human-readable name for a symbol. * Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead. @@ -3592,7 +3612,13 @@ namespace ts { * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`. */ function getNameOfSymbolAsWritten(symbol: Symbol, context?: NodeBuilderContext): string { - if (context && context.flags & NodeBuilderFlags.WriteDefaultSymbolWithoutName && symbol.escapedName === InternalSymbolName.Default) { + if (context && symbol.escapedName === InternalSymbolName.Default && !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope) && + // If it's not the first part of an entity name, it must print as `default` + (!(context.flags & NodeBuilderFlags.InInitialEntityName) || + // if the symbol is synthesized, it will only be referenced externally it must print as `default` + !symbol.declarations || + // if not in the same binding context (source file, module declaration), it must print as `default` + (context.enclosingDeclaration && findAncestor(symbol.declarations[0], isDefaultBindingContext) !== findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) { return "default"; } if (symbol.declarations && symbol.declarations.length) { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 1a35f520ce5..96ef4afc8da 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -358,7 +358,7 @@ namespace ts { } else { errorNameNode = declaration.name; - const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteDefaultSymbolWithoutName | + const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | (shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0); resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer); @@ -378,7 +378,7 @@ namespace ts { resolver.writeReturnTypeOfSignatureDeclaration( signature, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral, writer); errorNameNode = undefined; } @@ -643,7 +643,7 @@ namespace ts { resolver.writeTypeOfExpression( expr, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral, writer); write(";"); writeLine(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ce2c10a8dda..30eb5189611 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2937,7 +2937,7 @@ namespace ts { // Options NoTruncation = 1 << 0, // Don't truncate result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] - WriteDefaultSymbolWithoutName = 1 << 2, // Write `default`-named symbols as `default` instead of how they were written + // empty space UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible // empty space WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature @@ -2965,6 +2965,7 @@ namespace ts { // State InObjectTypeLiteral = 1 << 22, InTypeAlias = 1 << 23, // Writing type in type alias declaration + InInitialEntityName = 1 << 24, // Set when writing the LHS of an entity name or entity name expression } // Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment @@ -2972,7 +2973,7 @@ namespace ts { None = 0, NoTruncation = 1 << 0, // Don't truncate typeToString result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] - WriteDefaultSymbolWithoutName = 1 << 2, // Write all `defaut`-named symbols as `default` instead of their written name + // hole because there's a hole in node builder flags UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible // hole because there's a hole in node builder flags WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature @@ -3003,7 +3004,7 @@ namespace ts { /** @deprecated */ WriteOwnNameForAnyLike = 0, // Does nothing NodeBuilderFlagsMask = - NoTruncation | WriteArrayAsGenericType | WriteDefaultSymbolWithoutName | UseStructuralFallback | WriteTypeArgumentsOfSignature | + NoTruncation | WriteArrayAsGenericType | UseStructuralFallback | WriteTypeArgumentsOfSignature | UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias, } @@ -3024,6 +3025,9 @@ namespace ts { // Build symbol name using any nodes needed, instead of just components of an entity name AllowAnyNodeKind = 0x00000004, + + // Prefer aliases which are not directly visible + UseAliasDefinedOutsideCurrentScope = 0x00000008, } /* @internal */ diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 734912b3ffc..aa30ba0de6f 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -353,6 +353,7 @@ namespace ts.SignatureHelp { return children[indexOfOpenerToken + 1]; } + const signatureHelpNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors; function createSignatureHelpItems(candidates: Signature[], resolvedSignature: Signature, argumentListInfo: ArgumentListInfo, typeChecker: TypeChecker): SignatureHelpItems { const { argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex } = argumentListInfo; const isTypeParameterList = argumentListInfo.kind === ArgumentListKind.TypeArguments; @@ -378,9 +379,8 @@ namespace ts.SignatureHelp { signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken)); const parameterParts = mapToDisplayParts(writer => { - const flags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors; - const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, invocation, flags)] : []; - const params = createNodeArray([...thisParameter, ...map(candidateSignature.parameters, param => typeChecker.symbolToParameterDeclaration(param, invocation, flags))]); + const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, invocation, signatureHelpNodeBuilderFlags)] : []; + const params = createNodeArray([...thisParameter, ...map(candidateSignature.parameters, param => typeChecker.symbolToParameterDeclaration(param, invocation, signatureHelpNodeBuilderFlags))]); printer.writeList(ListFormat.CallExpressionArguments, params, getSourceFileOfNode(getParseTreeNode(invocation)), writer); }); addRange(suffixDisplayParts, parameterParts); @@ -435,7 +435,7 @@ namespace ts.SignatureHelp { function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { const displayParts = mapToDisplayParts(writer => { - const param = typeChecker.symbolToParameterDeclaration(parameter, invocation, NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors); + const param = typeChecker.symbolToParameterDeclaration(parameter, invocation, signatureHelpNodeBuilderFlags); printer.writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(invocation)), writer); }); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index e30fd8cfe2d..8b4bb1ad212 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1300,7 +1300,7 @@ namespace ts { export function symbolToDisplayParts(typeChecker: TypeChecker, symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags, writer); + typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags | SymbolFormatFlags.UseAliasDefinedOutsideCurrentScope, writer); }); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 78f68a80c50..921cff852d4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1799,7 +1799,6 @@ declare namespace ts { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, - WriteDefaultSymbolWithoutName = 4, UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, @@ -1821,12 +1820,12 @@ declare namespace ts { IgnoreErrors = 3112960, InObjectTypeLiteral = 4194304, InTypeAlias = 8388608, + InInitialEntityName = 16777216, } enum TypeFormatFlags { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, - WriteDefaultSymbolWithoutName = 4, UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, @@ -1844,13 +1843,14 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469295, + NodeBuilderFlagsMask = 9469291, } enum SymbolFormatFlags { None = 0, WriteTypeParametersOrArguments = 1, UseOnlyExternalAliasing = 2, AllowAnyNodeKind = 4, + UseAliasDefinedOutsideCurrentScope = 8, } /** * @deprecated diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 6a0a701ca1a..36094eeaa9e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1799,7 +1799,6 @@ declare namespace ts { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, - WriteDefaultSymbolWithoutName = 4, UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, @@ -1821,12 +1820,12 @@ declare namespace ts { IgnoreErrors = 3112960, InObjectTypeLiteral = 4194304, InTypeAlias = 8388608, + InInitialEntityName = 16777216, } enum TypeFormatFlags { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, - WriteDefaultSymbolWithoutName = 4, UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, @@ -1844,13 +1843,14 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469295, + NodeBuilderFlagsMask = 9469291, } enum SymbolFormatFlags { None = 0, WriteTypeParametersOrArguments = 1, UseOnlyExternalAliasing = 2, AllowAnyNodeKind = 4, + UseAliasDefinedOutsideCurrentScope = 8, } /** * @deprecated diff --git a/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols b/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols index 898a9883781..195f10a78a1 100644 --- a/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols +++ b/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols @@ -7,7 +7,7 @@ import * as a from "./a"; >a : Symbol(a, Decl(b.ts, 0, 6)) export default a.default; ->a.default : Symbol(a.C, Decl(a.ts, 0, 0)) +>a.default : Symbol(a.default, Decl(a.ts, 0, 0)) >a : Symbol(a, Decl(b.ts, 0, 6)) ->default : Symbol(a.C, Decl(a.ts, 0, 0)) +>default : Symbol(a.default, Decl(a.ts, 0, 0)) diff --git a/tests/baselines/reference/declarationEmitTypeofDefaultExport.types b/tests/baselines/reference/declarationEmitTypeofDefaultExport.types index 9cdd56d0cfb..115c20f9df7 100644 --- a/tests/baselines/reference/declarationEmitTypeofDefaultExport.types +++ b/tests/baselines/reference/declarationEmitTypeofDefaultExport.types @@ -7,7 +7,7 @@ import * as a from "./a"; >a : typeof a export default a.default; ->a.default : typeof a.C +>a.default : typeof a.default >a : typeof a ->default : typeof a.C +>default : typeof a.default diff --git a/tests/baselines/reference/defaultDeclarationEmitDefaultImport.js b/tests/baselines/reference/defaultDeclarationEmitDefaultImport.js new file mode 100644 index 00000000000..f978e568e87 --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitDefaultImport.js @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/defaultDeclarationEmitDefaultImport.ts] //// + +//// [root.ts] +export function getSomething(): Something { return null as any } +export default class Something {} +//// [main.ts] +import Thing, { getSomething } from "./root"; +export const instance = getSomething(); + + +//// [root.js] +"use strict"; +exports.__esModule = true; +function getSomething() { return null; } +exports.getSomething = getSomething; +var Something = /** @class */ (function () { + function Something() { + } + return Something; +}()); +exports["default"] = Something; +//// [main.js] +"use strict"; +exports.__esModule = true; +var root_1 = require("./root"); +exports.instance = root_1.getSomething(); + + +//// [root.d.ts] +export declare function getSomething(): Something; +export default class Something { +} +//// [main.d.ts] +import Thing from "./root"; +export declare const instance: Thing; diff --git a/tests/baselines/reference/defaultDeclarationEmitDefaultImport.symbols b/tests/baselines/reference/defaultDeclarationEmitDefaultImport.symbols new file mode 100644 index 00000000000..4db3a86d8bc --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitDefaultImport.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/root.ts === +export function getSomething(): Something { return null as any } +>getSomething : Symbol(getSomething, Decl(root.ts, 0, 0)) +>Something : Symbol(Something, Decl(root.ts, 0, 64)) + +export default class Something {} +>Something : Symbol(Something, Decl(root.ts, 0, 64)) + +=== tests/cases/compiler/main.ts === +import Thing, { getSomething } from "./root"; +>Thing : Symbol(Thing, Decl(main.ts, 0, 6)) +>getSomething : Symbol(getSomething, Decl(main.ts, 0, 15)) + +export const instance = getSomething(); +>instance : Symbol(instance, Decl(main.ts, 1, 12)) +>getSomething : Symbol(getSomething, Decl(main.ts, 0, 15)) + diff --git a/tests/baselines/reference/defaultDeclarationEmitDefaultImport.types b/tests/baselines/reference/defaultDeclarationEmitDefaultImport.types new file mode 100644 index 00000000000..5a7ff406001 --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitDefaultImport.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/root.ts === +export function getSomething(): Something { return null as any } +>getSomething : () => Something +>Something : Something +>null as any : any +>null : null + +export default class Something {} +>Something : Something + +=== tests/cases/compiler/main.ts === +import Thing, { getSomething } from "./root"; +>Thing : typeof Thing +>getSomething : () => Thing + +export const instance = getSomething(); +>instance : Thing +>getSomething() : Thing +>getSomething : () => Thing + diff --git a/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.js b/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.js new file mode 100644 index 00000000000..f28d8ee078a --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.js @@ -0,0 +1,49 @@ +//// [defaultDeclarationEmitNamedCorrectly.ts] +export interface Things { + p: P; + t: T; +} +export function make(x: { new (): CTor & {props: P} }): Things { + return null as any; +} + +export interface Props { +} + +export default class MyComponent { + props: Props; + static create = make(MyComponent); +} + +//// [defaultDeclarationEmitNamedCorrectly.js] +"use strict"; +exports.__esModule = true; +function make(x) { + return null; +} +exports.make = make; +var MyComponent = /** @class */ (function () { + function MyComponent() { + } + MyComponent.create = make(MyComponent); + return MyComponent; +}()); +exports["default"] = MyComponent; + + +//// [defaultDeclarationEmitNamedCorrectly.d.ts] +export interface Things { + p: P; + t: T; +} +export declare function make(x: { + new (): CTor & { + props: P; + }; +}): Things; +export interface Props { +} +export default class MyComponent { + props: Props; + static create: Things; +} diff --git a/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.symbols b/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.symbols new file mode 100644 index 00000000000..cd4cf923935 --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.symbols @@ -0,0 +1,45 @@ +=== tests/cases/compiler/defaultDeclarationEmitNamedCorrectly.ts === +export interface Things { +>Things : Symbol(Things, Decl(defaultDeclarationEmitNamedCorrectly.ts, 0, 0)) +>P : Symbol(P, Decl(defaultDeclarationEmitNamedCorrectly.ts, 0, 24)) +>T : Symbol(T, Decl(defaultDeclarationEmitNamedCorrectly.ts, 0, 26)) + + p: P; +>p : Symbol(Things.p, Decl(defaultDeclarationEmitNamedCorrectly.ts, 0, 31)) +>P : Symbol(P, Decl(defaultDeclarationEmitNamedCorrectly.ts, 0, 24)) + + t: T; +>t : Symbol(Things.t, Decl(defaultDeclarationEmitNamedCorrectly.ts, 1, 9)) +>T : Symbol(T, Decl(defaultDeclarationEmitNamedCorrectly.ts, 0, 26)) +} +export function make(x: { new (): CTor & {props: P} }): Things { +>make : Symbol(make, Decl(defaultDeclarationEmitNamedCorrectly.ts, 3, 1)) +>P : Symbol(P, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 21)) +>CTor : Symbol(CTor, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 23)) +>x : Symbol(x, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 30)) +>CTor : Symbol(CTor, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 23)) +>props : Symbol(props, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 51)) +>P : Symbol(P, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 21)) +>Things : Symbol(Things, Decl(defaultDeclarationEmitNamedCorrectly.ts, 0, 0)) +>P : Symbol(P, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 21)) +>CTor : Symbol(CTor, Decl(defaultDeclarationEmitNamedCorrectly.ts, 4, 23)) + + return null as any; +} + +export interface Props { +>Props : Symbol(Props, Decl(defaultDeclarationEmitNamedCorrectly.ts, 6, 1)) +} + +export default class MyComponent { +>MyComponent : Symbol(MyComponent, Decl(defaultDeclarationEmitNamedCorrectly.ts, 9, 1)) + + props: Props; +>props : Symbol(MyComponent.props, Decl(defaultDeclarationEmitNamedCorrectly.ts, 11, 34)) +>Props : Symbol(Props, Decl(defaultDeclarationEmitNamedCorrectly.ts, 6, 1)) + + static create = make(MyComponent); +>create : Symbol(MyComponent.create, Decl(defaultDeclarationEmitNamedCorrectly.ts, 12, 17)) +>make : Symbol(make, Decl(defaultDeclarationEmitNamedCorrectly.ts, 3, 1)) +>MyComponent : Symbol(MyComponent, Decl(defaultDeclarationEmitNamedCorrectly.ts, 9, 1)) +} diff --git a/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.types b/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.types new file mode 100644 index 00000000000..998dff74b23 --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitNamedCorrectly.types @@ -0,0 +1,48 @@ +=== tests/cases/compiler/defaultDeclarationEmitNamedCorrectly.ts === +export interface Things { +>Things : Things +>P : P +>T : T + + p: P; +>p : P +>P : P + + t: T; +>t : T +>T : T +} +export function make(x: { new (): CTor & {props: P} }): Things { +>make : (x: new () => CTor & { props: P; }) => Things +>P : P +>CTor : CTor +>x : new () => CTor & { props: P; } +>CTor : CTor +>props : P +>P : P +>Things : Things +>P : P +>CTor : CTor + + return null as any; +>null as any : any +>null : null +} + +export interface Props { +>Props : Props +} + +export default class MyComponent { +>MyComponent : MyComponent + + props: Props; +>props : Props +>Props : Props + + static create = make(MyComponent); +>create : Things +>make(MyComponent) : Things +>make : (x: new () => CTor & { props: P; }) => Things +>MyComponent : typeof MyComponent +} diff --git a/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.js b/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.js new file mode 100644 index 00000000000..9367a8fc374 --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.js @@ -0,0 +1,61 @@ +//// [this.ts] +import * as me from "./this"; +export interface Things { + p: P; + t: T; +} +export function make(x: { new (): CTor & {props: P} }): Things { + return null as any; +} + +export interface Props { +} + +export default class MyComponent { + props: Props; +} +export namespace Something { + let MyComponent = 2; // Shadow declaration, so symbol is only usable via the self-import + export const create = make(me.default); +} + +//// [this.js] +"use strict"; +exports.__esModule = true; +var me = require("./this"); +function make(x) { + return null; +} +exports.make = make; +var MyComponent = /** @class */ (function () { + function MyComponent() { + } + return MyComponent; +}()); +exports["default"] = MyComponent; +var Something; +(function (Something) { + var MyComponent = 2; // Shadow declaration, so symbol is only usable via the self-import + Something.create = make(me["default"]); +})(Something = exports.Something || (exports.Something = {})); + + +//// [this.d.ts] +import * as me from "./this"; +export interface Things { + p: P; + t: T; +} +export declare function make(x: { + new (): CTor & { + props: P; + }; +}): Things; +export interface Props { +} +export default class MyComponent { + props: Props; +} +export declare namespace Something { + const create: me.Things; +} diff --git a/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.symbols b/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.symbols new file mode 100644 index 00000000000..703c5ebd4e3 --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.symbols @@ -0,0 +1,56 @@ +=== tests/cases/compiler/this.ts === +import * as me from "./this"; +>me : Symbol(me, Decl(this.ts, 0, 6)) + +export interface Things { +>Things : Symbol(me.Things, Decl(this.ts, 0, 29)) +>P : Symbol(P, Decl(this.ts, 1, 24)) +>T : Symbol(T, Decl(this.ts, 1, 26)) + + p: P; +>p : Symbol(me.Things.p, Decl(this.ts, 1, 31)) +>P : Symbol(P, Decl(this.ts, 1, 24)) + + t: T; +>t : Symbol(me.Things.t, Decl(this.ts, 2, 9)) +>T : Symbol(T, Decl(this.ts, 1, 26)) +} +export function make(x: { new (): CTor & {props: P} }): Things { +>make : Symbol(me.make, Decl(this.ts, 4, 1)) +>P : Symbol(P, Decl(this.ts, 5, 21)) +>CTor : Symbol(CTor, Decl(this.ts, 5, 23)) +>x : Symbol(x, Decl(this.ts, 5, 30)) +>CTor : Symbol(CTor, Decl(this.ts, 5, 23)) +>props : Symbol(props, Decl(this.ts, 5, 51)) +>P : Symbol(P, Decl(this.ts, 5, 21)) +>Things : Symbol(me.Things, Decl(this.ts, 0, 29)) +>P : Symbol(P, Decl(this.ts, 5, 21)) +>CTor : Symbol(CTor, Decl(this.ts, 5, 23)) + + return null as any; +} + +export interface Props { +>Props : Symbol(me.Props, Decl(this.ts, 7, 1)) +} + +export default class MyComponent { +>MyComponent : Symbol(me.default, Decl(this.ts, 10, 1)) + + props: Props; +>props : Symbol(me.default.props, Decl(this.ts, 12, 34)) +>Props : Symbol(me.Props, Decl(this.ts, 7, 1)) +} +export namespace Something { +>Something : Symbol(me.Something, Decl(this.ts, 14, 1)) + + let MyComponent = 2; // Shadow declaration, so symbol is only usable via the self-import +>MyComponent : Symbol(MyComponent, Decl(this.ts, 16, 7)) + + export const create = make(me.default); +>create : Symbol(create, Decl(this.ts, 17, 16)) +>make : Symbol(me.make, Decl(this.ts, 4, 1)) +>me.default : Symbol(me.default, Decl(this.ts, 10, 1)) +>me : Symbol(me, Decl(this.ts, 0, 6)) +>default : Symbol(me.default, Decl(this.ts, 10, 1)) +} diff --git a/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.types b/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.types new file mode 100644 index 00000000000..170738eea58 --- /dev/null +++ b/tests/baselines/reference/defaultDeclarationEmitShadowedNamedCorrectly.types @@ -0,0 +1,60 @@ +=== tests/cases/compiler/this.ts === +import * as me from "./this"; +>me : typeof me + +export interface Things { +>Things : me.Things +>P : P +>T : T + + p: P; +>p : P +>P : P + + t: T; +>t : T +>T : T +} +export function make(x: { new (): CTor & {props: P} }): Things { +>make : (x: new () => CTor & { props: P; }) => me.Things +>P : P +>CTor : CTor +>x : new () => CTor & { props: P; } +>CTor : CTor +>props : P +>P : P +>Things : me.Things +>P : P +>CTor : CTor + + return null as any; +>null as any : any +>null : null +} + +export interface Props { +>Props : me.Props +} + +export default class MyComponent { +>MyComponent : me.default + + props: Props; +>props : me.Props +>Props : me.Props +} +export namespace Something { +>Something : typeof me.Something + + let MyComponent = 2; // Shadow declaration, so symbol is only usable via the self-import +>MyComponent : number +>2 : 2 + + export const create = make(me.default); +>create : me.Things +>make(me.default) : me.Things +>make : (x: new () => CTor & { props: P; }) => me.Things +>me.default : typeof me.default +>me : typeof me +>default : typeof me.default +} diff --git a/tests/baselines/reference/duplicatePackage.types b/tests/baselines/reference/duplicatePackage.types index 4b0a4500f14..689d7a5c5bc 100644 --- a/tests/baselines/reference/duplicatePackage.types +++ b/tests/baselines/reference/duplicatePackage.types @@ -1,22 +1,22 @@ === /src/a.ts === import { a } from "a"; ->a : (x: X) => void +>a : (x: default) => void import { b } from "b"; ->b : X +>b : default import { c } from "c"; ->c : X +>c : default a(b); // Works >a(b) : void ->a : (x: X) => void ->b : X +>a : (x: default) => void +>b : default a(c); // Error, these are from different versions of the library. >a(c) : void ->a : (x: X) => void ->c : X +>a : (x: default) => void +>c : default === /node_modules/a/index.d.ts === import X from "x"; diff --git a/tests/cases/compiler/defaultDeclarationEmitDefaultImport.ts b/tests/cases/compiler/defaultDeclarationEmitDefaultImport.ts new file mode 100644 index 00000000000..3ff8c22ddf0 --- /dev/null +++ b/tests/cases/compiler/defaultDeclarationEmitDefaultImport.ts @@ -0,0 +1,7 @@ +// @declaration: true +// @filename: root.ts +export function getSomething(): Something { return null as any } +export default class Something {} +// @filename: main.ts +import Thing, { getSomething } from "./root"; +export const instance = getSomething(); diff --git a/tests/cases/compiler/defaultDeclarationEmitNamedCorrectly.ts b/tests/cases/compiler/defaultDeclarationEmitNamedCorrectly.ts new file mode 100644 index 00000000000..5be4e0e19b6 --- /dev/null +++ b/tests/cases/compiler/defaultDeclarationEmitNamedCorrectly.ts @@ -0,0 +1,16 @@ +// @declaration: true +export interface Things { + p: P; + t: T; +} +export function make(x: { new (): CTor & {props: P} }): Things { + return null as any; +} + +export interface Props { +} + +export default class MyComponent { + props: Props; + static create = make(MyComponent); +} \ No newline at end of file diff --git a/tests/cases/compiler/defaultDeclarationEmitShadowedNamedCorrectly.ts b/tests/cases/compiler/defaultDeclarationEmitShadowedNamedCorrectly.ts new file mode 100644 index 00000000000..e5fba0d3986 --- /dev/null +++ b/tests/cases/compiler/defaultDeclarationEmitShadowedNamedCorrectly.ts @@ -0,0 +1,21 @@ +// @declaration: true +// @filename: this.ts +import * as me from "./this"; +export interface Things { + p: P; + t: T; +} +export function make(x: { new (): CTor & {props: P} }): Things { + return null as any; +} + +export interface Props { +} + +export default class MyComponent { + props: Props; +} +export namespace Something { + let MyComponent = 2; // Shadow declaration, so symbol is only usable via the self-import + export const create = make(me.default); +} \ No newline at end of file From 421c9271508d4acb0968c2d9efd7fb2e7979f25d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 1 Feb 2018 12:52:51 -0800 Subject: [PATCH 30/42] Add formik to the user suite (#21381) * Add formik to user suite * Accept current log --- tests/baselines/reference/user/formik.log | 31 ++++++++ tests/cases/user/formik/index.tsx | 94 +++++++++++++++++++++++ tests/cases/user/formik/package.json | 16 ++++ tests/cases/user/formik/tsconfig.json | 12 +++ 4 files changed, 153 insertions(+) create mode 100644 tests/baselines/reference/user/formik.log create mode 100644 tests/cases/user/formik/index.tsx create mode 100644 tests/cases/user/formik/package.json create mode 100644 tests/cases/user/formik/tsconfig.json diff --git a/tests/baselines/reference/user/formik.log b/tests/baselines/reference/user/formik.log new file mode 100644 index 00000000000..30767a636c9 --- /dev/null +++ b/tests/baselines/reference/user/formik.log @@ -0,0 +1,31 @@ +Exit Code: 1 +Standard output: +index.tsx(26,7): error TS2322: Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes, object>> & Readonly<{...'. + Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'Readonly>'. + Types of property 'onSubmit' are incompatible. + Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '(values: object, formikActions: FormikActions) => void'. +index.tsx(26,7): error TS2322: Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes, object>> & Readonly<{...'. + Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'Readonly>'. + Types of property 'onSubmit' are incompatible. + Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '(values: object, formikActions: FormikActions) => void'. + Types of parameters 'values' and 'values' are incompatible. + Type 'object' is not assignable to type 'Values'. +index.tsx(32,13): error TS2322: Type '{}' is not assignable to type 'FormikErrors'. + Property 'email' is missing in type '{}'. +index.tsx(33,21): error TS2339: Property 'email' does not exist on type 'Values'. +index.tsx(36,68): error TS2339: Property 'email' does not exist on type 'Values'. +index.tsx(46,22): error TS2345: Argument of type 'Values' is not assignable to parameter of type 'MyData'. +index.tsx(47,11): error TS7006: Parameter 'user' implicitly has an 'any' type. +index.tsx(52,11): error TS7006: Parameter 'errors' implicitly has an 'any' type. +index.tsx(74,27): error TS2339: Property 'email' does not exist on type 'Values'. +index.tsx(76,20): error TS2339: Property 'email' does not exist on type 'FormikTouched'. +index.tsx(76,36): error TS2339: Property 'email' does not exist on type 'FormikErrors'. +index.tsx(76,58): error TS2339: Property 'email' does not exist on type 'FormikErrors'. +index.tsx(82,27): error TS2339: Property 'password' does not exist on type 'Values'. +index.tsx(84,20): error TS2339: Property 'password' does not exist on type 'FormikTouched'. +index.tsx(84,39): error TS2339: Property 'password' does not exist on type 'FormikErrors'. +index.tsx(84,64): error TS2339: Property 'password' does not exist on type 'FormikErrors'. + + + +Standard error: diff --git a/tests/cases/user/formik/index.tsx b/tests/cases/user/formik/index.tsx new file mode 100644 index 00000000000..04e06cbd193 --- /dev/null +++ b/tests/cases/user/formik/index.tsx @@ -0,0 +1,94 @@ +// Render Prop +import React from 'react'; +import { Formik, FormikErrors } from 'formik'; + +type MyData = {email: string, password: string}; +declare function LoginToMyApp(data: MyData): Promise<{user: string}>; +declare function transformMyApiErrors(o: any): FormikErrors; + +const Basic = () => ( +
+

My Form

+

This can be anywhere in your application

+ {/* + The benefit of the render prop approach is that you have full access to React's + state, props, and composition model. Thus there is no need to map outer props + to values...you can just set the initial values, and if they depend on props / state + then--boom--you can directly access to props / state. + + The render prop accepts your inner form component, which you can define separately or inline + totally up to you: + - `
...
}>` + - `` + - `{props =>
...
}
` (identical to as render, just written differently) + */} + { + // same as above, but feel free to move this into a class method now. + let errors: FormikErrors = {}; + if (!values.email) { + errors.email = 'Required'; + } else if ( + !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) + ) { + errors.email = 'Invalid email address'; + } + return errors; + }} + onSubmit={( + values, + { setSubmitting, setErrors /* setValues and other goodies */ } + ) => { + LoginToMyApp(values).then( + user => { + setSubmitting(false); + // do whatevs... + // props.updateUser(user) + }, + errors => { + setSubmitting(false); + // Maybe transform your API's errors into the same shape as Formik's + setErrors(transformMyApiErrors(errors)); + } + ); + }} + render={({ + values, + errors, + touched, + handleChange, + handleBlur, + handleSubmit, + isSubmitting, + }) => ( +
+ + {touched.email && errors.email &&
{errors.email}
} + + {touched.password && errors.password &&
{errors.password}
} + +
+ )} + /> +
+); + +export default Basic; \ No newline at end of file diff --git a/tests/cases/user/formik/package.json b/tests/cases/user/formik/package.json new file mode 100644 index 00000000000..9641ca9aea6 --- /dev/null +++ b/tests/cases/user/formik/package.json @@ -0,0 +1,16 @@ +{ + "name": "formik", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "Apache-2.0", + "dependencies": { + "formik": "latest", + "@types/react": "latest", + "@types/prop-types": "latest" + } +} diff --git a/tests/cases/user/formik/tsconfig.json b/tests/cases/user/formik/tsconfig.json new file mode 100644 index 00000000000..860e282bdf0 --- /dev/null +++ b/tests/cases/user/formik/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "jsx": "react", + "strict": true, + "esModuleInterop": true, + "noEmit": true, + "types": [] + }, + "files": [ + "index.tsx" + ] +} \ No newline at end of file From 94b2d40caca13f8980c4fd7a902f762c753ef2ba Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 1 Feb 2018 15:22:34 -0800 Subject: [PATCH 31/42] Fix over-aggressive transformation of super properties --- src/compiler/transformers/es2015.ts | 113 ++++++++++-------- .../baselines/reference/superElementAccess.js | 5 +- .../reference/superPropertyAccess.js | 5 +- 3 files changed, 64 insertions(+), 59 deletions(-) diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index da0fcc73a98..0956c1075ef 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3439,64 +3439,71 @@ namespace ts { function visitCallExpressionWithPotentialCapturedThisAssignment(node: CallExpression, assignToCapturedThis: boolean): CallExpression | BinaryExpression { // We are here either because SuperKeyword was used somewhere in the expression, or // because we contain a SpreadElementExpression. + if (node.transformFlags & TransformFlags.ContainsSpread || + node.expression.kind === SyntaxKind.SuperKeyword || + isSuperProperty(skipOuterExpressions(node.expression))) { - const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration); - if (node.expression.kind === SyntaxKind.SuperKeyword) { - setEmitFlags(thisArg, EmitFlags.NoSubstitution); - } - let resultingCall: CallExpression | BinaryExpression; - if (node.transformFlags & TransformFlags.ContainsSpread) { - // [source] - // f(...a, b) - // x.m(...a, b) - // super(...a, b) - // super.m(...a, b) // in static - // super.m(...a, b) // in instance - // - // [output] - // f.apply(void 0, a.concat([b])) - // (_a = x).m.apply(_a, a.concat([b])) - // _super.apply(this, a.concat([b])) - // _super.m.apply(this, a.concat([b])) - // _super.prototype.m.apply(this, a.concat([b])) + const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration); + if (node.expression.kind === SyntaxKind.SuperKeyword) { + setEmitFlags(thisArg, EmitFlags.NoSubstitution); + } - resultingCall = createFunctionApply( - visitNode(target, callExpressionVisitor, isExpression), - visitNode(thisArg, visitor, isExpression), - transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) - ); - } - else { - // [source] - // super(a) - // super.m(a) // in static - // super.m(a) // in instance - // - // [output] - // _super.call(this, a) - // _super.m.call(this, a) - // _super.prototype.m.call(this, a) - resultingCall = createFunctionCall( - visitNode(target, callExpressionVisitor, isExpression), - visitNode(thisArg, visitor, isExpression), - visitNodes(node.arguments, visitor, isExpression), - /*location*/ node - ); - } + let resultingCall: CallExpression | BinaryExpression; + if (node.transformFlags & TransformFlags.ContainsSpread) { + // [source] + // f(...a, b) + // x.m(...a, b) + // super(...a, b) + // super.m(...a, b) // in static + // super.m(...a, b) // in instance + // + // [output] + // f.apply(void 0, a.concat([b])) + // (_a = x).m.apply(_a, a.concat([b])) + // _super.apply(this, a.concat([b])) + // _super.m.apply(this, a.concat([b])) + // _super.prototype.m.apply(this, a.concat([b])) - if (node.expression.kind === SyntaxKind.SuperKeyword) { - const actualThis = createThis(); - setEmitFlags(actualThis, EmitFlags.NoSubstitution); - const initializer = - createLogicalOr( - resultingCall, - actualThis + resultingCall = createFunctionApply( + visitNode(target, callExpressionVisitor, isExpression), + visitNode(thisArg, visitor, isExpression), + transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) ); - resultingCall = assignToCapturedThis - ? createAssignment(createIdentifier("_this"), initializer) - : initializer; + } + else { + // [source] + // super(a) + // super.m(a) // in static + // super.m(a) // in instance + // + // [output] + // _super.call(this, a) + // _super.m.call(this, a) + // _super.prototype.m.call(this, a) + resultingCall = createFunctionCall( + visitNode(target, callExpressionVisitor, isExpression), + visitNode(thisArg, visitor, isExpression), + visitNodes(node.arguments, visitor, isExpression), + /*location*/ node + ); + } + + if (node.expression.kind === SyntaxKind.SuperKeyword) { + const actualThis = createThis(); + setEmitFlags(actualThis, EmitFlags.NoSubstitution); + const initializer = + createLogicalOr( + resultingCall, + actualThis + ); + resultingCall = assignToCapturedThis + ? createAssignment(createIdentifier("_this"), initializer) + : initializer; + } + return setOriginalNode(resultingCall, node); } - return setOriginalNode(resultingCall, node); + + return visitEachChild(node, visitor, context); } /** diff --git a/tests/baselines/reference/superElementAccess.js b/tests/baselines/reference/superElementAccess.js index 422b80109bb..75789b523c8 100644 --- a/tests/baselines/reference/superElementAccess.js +++ b/tests/baselines/reference/superElementAccess.js @@ -69,16 +69,15 @@ var MyDerived = /** @class */ (function (_super) { } MyDerived.prototype.foo = function () { _super.prototype["m1"].call(this, "hi"); // Should be allowed, method on base prototype - var l2 = (_a = _super.prototype["m1"]).bind.call(_a, this); // Should be allowed, can access properties as well as invoke + var l2 = _super.prototype["m1"].bind(this); // Should be allowed, can access properties as well as invoke var x = _super.prototype["m1"]; // Should be allowed, can assign to var with compatible signature - (_b = _super.prototype["m2"]).bind.call(_b, this); // Should error, instance property, not a public instance member function + _super.prototype["m2"].bind(this); // Should error, instance property, not a public instance member function _super.prototype["p1"].call(this); // Should error, private not public instance member function var l1 = _super.prototype["d1"]; // Should error, instance data property not a public instance member function var l1 = _super.prototype["d2"]; // Should error, instance data property not a public instance member function _super.prototype["m1"] = function (a) { return ""; }; // Should be allowed, we will not restrict assignment _super.prototype["value"] = 0; // Should error, instance data property not a public instance member function var z = _super.prototype["value"]; // Should error, instance data property not a public instance member function - var _a, _b; }; return MyDerived; }(MyBase)); diff --git a/tests/baselines/reference/superPropertyAccess.js b/tests/baselines/reference/superPropertyAccess.js index 8fa0984745c..cc9758a1617 100644 --- a/tests/baselines/reference/superPropertyAccess.js +++ b/tests/baselines/reference/superPropertyAccess.js @@ -69,16 +69,15 @@ var MyDerived = /** @class */ (function (_super) { } MyDerived.prototype.foo = function () { _super.prototype.m1.call(this, "hi"); // Should be allowed, method on base prototype - var l2 = (_a = _super.prototype.m1).bind.call(_a, this); // Should be allowed, can access properties as well as invoke + var l2 = _super.prototype.m1.bind(this); // Should be allowed, can access properties as well as invoke var x = _super.prototype.m1; // Should be allowed, can assign to var with compatible signature - (_b = _super.prototype.m2).bind.call(_b, this); // Should error, instance property, not a public instance member function + _super.prototype.m2.bind(this); // Should error, instance property, not a public instance member function _super.prototype.p1.call(this); // Should error, private not public instance member function var l1 = _super.prototype.d1; // Should error, instance data property not a public instance member function var l1 = _super.prototype.d2; // Should error, instance data property not a public instance member function _super.prototype.m1 = function (a) { return ""; }; // Should be allowed, we will not restrict assignment _super.prototype.value = 0; // Should error, instance data property not a public instance member function var z = _super.prototype.value; // Should error, instance data property not a public instance member function - var _a, _b; }; return MyDerived; }(MyBase)); From aa5272dc8930264ce9332239c741288732b7d5e5 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 1 Feb 2018 15:38:18 -0800 Subject: [PATCH 32/42] Create import helpers for named imports if they contain default imports (#21550) --- src/compiler/transformers/module/module.ts | 24 ++++++++- .../esModuleInteropNamedDefaultImports.js | 49 +++++++++++++++++++ ...esModuleInteropNamedDefaultImports.symbols | 32 ++++++++++++ .../esModuleInteropNamedDefaultImports.types | 36 ++++++++++++++ .../esModuleInteropNamedDefaultImports.ts | 13 +++++ 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/esModuleInteropNamedDefaultImports.js create mode 100644 tests/baselines/reference/esModuleInteropNamedDefaultImports.symbols create mode 100644 tests/baselines/reference/esModuleInteropNamedDefaultImports.types create mode 100644 tests/cases/compiler/esModuleInteropNamedDefaultImports.ts diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 0d4e5b6864a..aabc2bc45c1 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -690,16 +690,36 @@ namespace ts { return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); } + function getNamedImportCount(node: ImportDeclaration) { + if (!(node.importClause && node.importClause.namedBindings)) return 0; + const names = node.importClause.namedBindings; + if (!names) return 0; + if (!isNamedImports(names)) return 0; + return names.elements.length; + } + + function containsDefaultReference(node: NamedImportBindings) { + if (!node) return false; + if (!isNamedImports(node)) return false; + return some(node.elements, isNamedDefaultReference); + } + + function isNamedDefaultReference(e: ImportSpecifier) { + return e.propertyName && e.propertyName.escapedText === InternalSymbolName.Default; + } function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) { if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { return innerExpr; } - if (getNamespaceDeclarationNode(node)) { + const nameCount = getNamedImportCount(node); + const hasDefault = nameCount > 0 ? containsDefaultReference(node.importClause.namedBindings) : undefined; + + if (getNamespaceDeclarationNode(node) || (nameCount > 1 && hasDefault)) { context.requestEmitHelper(importStarHelper); return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]); } - if (isDefaultImport(node)) { + if (isDefaultImport(node) || (nameCount === 1 && hasDefault)) { context.requestEmitHelper(importDefaultHelper); return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]); } diff --git a/tests/baselines/reference/esModuleInteropNamedDefaultImports.js b/tests/baselines/reference/esModuleInteropNamedDefaultImports.js new file mode 100644 index 00000000000..d3a804b5e4c --- /dev/null +++ b/tests/baselines/reference/esModuleInteropNamedDefaultImports.js @@ -0,0 +1,49 @@ +//// [tests/cases/compiler/esModuleInteropNamedDefaultImports.ts] //// + +//// [mod.ts] +export default class Foo {} +export class Bar {} +//// [idx.ts] +import Foo from "./mod"; +import { default as Foo2 } from "./mod"; +import { Bar, default as Foo3 } from "./mod"; +new Foo(); +new Foo2(); +new Bar(); +new Foo3(); + +//// [mod.js] +"use strict"; +exports.__esModule = true; +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); +exports["default"] = Foo; +var Bar = /** @class */ (function () { + function Bar() { + } + return Bar; +}()); +exports.Bar = Bar; +//// [idx.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +} +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +exports.__esModule = true; +var mod_1 = __importDefault(require("./mod")); +var mod_2 = __importDefault(require("./mod")); +var mod_3 = __importStar(require("./mod")); +new mod_1["default"](); +new mod_2["default"](); +new mod_3.Bar(); +new mod_3["default"](); diff --git a/tests/baselines/reference/esModuleInteropNamedDefaultImports.symbols b/tests/baselines/reference/esModuleInteropNamedDefaultImports.symbols new file mode 100644 index 00000000000..5b84c591fea --- /dev/null +++ b/tests/baselines/reference/esModuleInteropNamedDefaultImports.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/mod.ts === +export default class Foo {} +>Foo : Symbol(Foo, Decl(mod.ts, 0, 0)) + +export class Bar {} +>Bar : Symbol(Bar, Decl(mod.ts, 0, 27)) + +=== tests/cases/compiler/idx.ts === +import Foo from "./mod"; +>Foo : Symbol(Foo, Decl(idx.ts, 0, 6)) + +import { default as Foo2 } from "./mod"; +>default : Symbol(Foo2, Decl(idx.ts, 1, 8)) +>Foo2 : Symbol(Foo2, Decl(idx.ts, 1, 8)) + +import { Bar, default as Foo3 } from "./mod"; +>Bar : Symbol(Bar, Decl(idx.ts, 2, 8)) +>default : Symbol(Foo3, Decl(idx.ts, 2, 13)) +>Foo3 : Symbol(Foo3, Decl(idx.ts, 2, 13)) + +new Foo(); +>Foo : Symbol(Foo, Decl(idx.ts, 0, 6)) + +new Foo2(); +>Foo2 : Symbol(Foo2, Decl(idx.ts, 1, 8)) + +new Bar(); +>Bar : Symbol(Bar, Decl(idx.ts, 2, 8)) + +new Foo3(); +>Foo3 : Symbol(Foo3, Decl(idx.ts, 2, 13)) + diff --git a/tests/baselines/reference/esModuleInteropNamedDefaultImports.types b/tests/baselines/reference/esModuleInteropNamedDefaultImports.types new file mode 100644 index 00000000000..3cc78be737d --- /dev/null +++ b/tests/baselines/reference/esModuleInteropNamedDefaultImports.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/mod.ts === +export default class Foo {} +>Foo : Foo + +export class Bar {} +>Bar : Bar + +=== tests/cases/compiler/idx.ts === +import Foo from "./mod"; +>Foo : typeof Foo + +import { default as Foo2 } from "./mod"; +>default : typeof Foo +>Foo2 : typeof Foo + +import { Bar, default as Foo3 } from "./mod"; +>Bar : typeof Bar +>default : typeof Foo +>Foo3 : typeof Foo + +new Foo(); +>new Foo() : Foo +>Foo : typeof Foo + +new Foo2(); +>new Foo2() : Foo +>Foo2 : typeof Foo + +new Bar(); +>new Bar() : Bar +>Bar : typeof Bar + +new Foo3(); +>new Foo3() : Foo +>Foo3 : typeof Foo + diff --git a/tests/cases/compiler/esModuleInteropNamedDefaultImports.ts b/tests/cases/compiler/esModuleInteropNamedDefaultImports.ts new file mode 100644 index 00000000000..4f4a4922c33 --- /dev/null +++ b/tests/cases/compiler/esModuleInteropNamedDefaultImports.ts @@ -0,0 +1,13 @@ +// @module: commonjs +// @esModuleInterop: true +// @filename: mod.ts +export default class Foo {} +export class Bar {} +// @filename: idx.ts +import Foo from "./mod"; +import { default as Foo2 } from "./mod"; +import { Bar, default as Foo3 } from "./mod"; +new Foo(); +new Foo2(); +new Bar(); +new Foo3(); \ No newline at end of file From 8b81d19b6db9267da5fa1fda8f7640cbac517c65 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 2 Feb 2018 00:30:03 -0800 Subject: [PATCH 33/42] Enable CFA on this keyword unconditionally (#21490) --- src/compiler/checker.ts | 6 +-- .../controlFlowAnalysisOnBareThisKeyword.js | 26 +++++++++++++ ...ntrolFlowAnalysisOnBareThisKeyword.symbols | 34 ++++++++++++++++ ...controlFlowAnalysisOnBareThisKeyword.types | 39 +++++++++++++++++++ .../controlFlowAnalysisOnBareThisKeyword.ts | 13 +++++++ 5 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.js create mode 100644 tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.symbols create mode 100644 tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.types create mode 100644 tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ad03dbe52e5..f6a9a90987a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13341,13 +13341,13 @@ namespace ts { .expression; // x const classSymbol = checkExpression(className).symbol; if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) { - return getInferredClassType(classSymbol); + return getFlowTypeOfReference(node, getInferredClassType(classSymbol)); } } const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); if (thisType) { - return thisType; + return getFlowTypeOfReference(node, thisType); } } @@ -13360,7 +13360,7 @@ namespace ts { if (isInJavaScriptFile(node)) { const type = getTypeForThisExpressionFromJSDoc(container); if (type && type !== unknownType) { - return type; + return getFlowTypeOfReference(node, type); } } } diff --git a/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.js b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.js new file mode 100644 index 00000000000..14edf1abca6 --- /dev/null +++ b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.js @@ -0,0 +1,26 @@ +//// [controlFlowAnalysisOnBareThisKeyword.ts] +declare function isBig(x: any): x is { big: true }; +function bigger(this: {}) { + if (isBig(this)) { + this.big; // Expect property to exist + } +} + +function bar(this: string | number) { + if (typeof this === "string") { + const x: string = this; + } +} + +//// [controlFlowAnalysisOnBareThisKeyword.js] +"use strict"; +function bigger() { + if (isBig(this)) { + this.big; // Expect property to exist + } +} +function bar() { + if (typeof this === "string") { + var x = this; + } +} diff --git a/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.symbols b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.symbols new file mode 100644 index 00000000000..f15dd5955d7 --- /dev/null +++ b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts === +declare function isBig(x: any): x is { big: true }; +>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0)) +>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23)) +>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23)) +>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38)) + +function bigger(this: {}) { +>bigger : Symbol(bigger, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 51)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16)) + + if (isBig(this)) { +>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16)) + + this.big; // Expect property to exist +>this.big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16)) +>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38)) + } +} + +function bar(this: string | number) { +>bar : Symbol(bar, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 5, 1)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13)) + + if (typeof this === "string") { +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13)) + + const x: string = this; +>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 9, 13)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13)) + } +} diff --git a/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.types b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.types new file mode 100644 index 00000000000..f44dd8ee685 --- /dev/null +++ b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts === +declare function isBig(x: any): x is { big: true }; +>isBig : (x: any) => x is { big: true; } +>x : any +>x : any +>big : true +>true : true + +function bigger(this: {}) { +>bigger : (this: {}) => void +>this : {} + + if (isBig(this)) { +>isBig(this) : boolean +>isBig : (x: any) => x is { big: true; } +>this : {} + + this.big; // Expect property to exist +>this.big : true +>this : { big: true; } +>big : true + } +} + +function bar(this: string | number) { +>bar : (this: string | number) => void +>this : string | number + + if (typeof this === "string") { +>typeof this === "string" : boolean +>typeof this : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>this : string | number +>"string" : "string" + + const x: string = this; +>x : string +>this : string + } +} diff --git a/tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts b/tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts new file mode 100644 index 00000000000..6ecf297a7c2 --- /dev/null +++ b/tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts @@ -0,0 +1,13 @@ +// @strict: true +declare function isBig(x: any): x is { big: true }; +function bigger(this: {}) { + if (isBig(this)) { + this.big; // Expect property to exist + } +} + +function bar(this: string | number) { + if (typeof this === "string") { + const x: string = this; + } +} \ No newline at end of file From 2047558daf550e054cbe7790880e40bdceb45dc7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 2 Feb 2018 07:47:42 -0800 Subject: [PATCH 34/42] Optimize creation of union and intersection types --- src/compiler/checker.ts | 135 +++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 64 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16b2091733a..d2ae5b4cea8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -580,6 +580,21 @@ namespace ts { Both = Source | Target, } + const enum TypeIncludes { + Any = 1 << 0, + Undefined = 1 << 1, + Null = 1 << 2, + Never = 1 << 3, + NonWideningType = 1 << 4, + String = 1 << 5, + Number = 1 << 6, + ESSymbol = 1 << 7, + LiteralOrUniqueESSymbol = 1 << 8, + ObjectType = 1 << 9, + EmptyObject = 1 << 10, + Union = 1 << 11, + } + const enum MembersOrExportsResolutionKind { resolvedExports = "resolvedExports", resolvedMembers = "resolvedMembers" @@ -5516,6 +5531,8 @@ namespace ts { sig.minArgumentCount = minArgumentCount; sig.hasRestParameter = hasRestParameter; sig.hasLiteralTypes = hasLiteralTypes; + sig.target = undefined; + sig.mapper = undefined; return sig; } @@ -7419,21 +7436,6 @@ namespace ts { return links.resolvedType; } - interface TypeSet extends Array { - containsAny?: boolean; - containsUndefined?: boolean; - containsNull?: boolean; - containsNever?: boolean; - containsNonWideningType?: boolean; - containsString?: boolean; - containsNumber?: boolean; - containsESSymbol?: boolean; - containsLiteralOrUniqueESSymbol?: boolean; - containsObjectType?: boolean; - containsEmptyObject?: boolean; - unionIndex?: number; - } - function getTypeId(type: Type) { return type.id; } @@ -7458,28 +7460,28 @@ namespace ts { return false; } - function addTypeToUnion(typeSet: TypeSet, type: Type) { + function addTypeToUnion(typeSet: Type[], includes: TypeIncludes, type: Type) { const flags = type.flags; if (flags & TypeFlags.Union) { - addTypesToUnion(typeSet, (type).types); + includes = addTypesToUnion(typeSet, includes, (type).types); } else if (flags & TypeFlags.Any) { - typeSet.containsAny = true; + includes |= TypeIncludes.Any; } else if (!strictNullChecks && flags & TypeFlags.Nullable) { - if (flags & TypeFlags.Undefined) typeSet.containsUndefined = true; - if (flags & TypeFlags.Null) typeSet.containsNull = true; - if (!(flags & TypeFlags.ContainsWideningType)) typeSet.containsNonWideningType = true; + if (flags & TypeFlags.Undefined) includes |= TypeIncludes.Undefined; + if (flags & TypeFlags.Null) includes |= TypeIncludes.Null; + if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeIncludes.NonWideningType; } else if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(type))) { // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are // another form of 'never' (in that they have an empty value domain). We could in theory turn // intersections of unit types into 'never' upon construction, but deferring the reduction makes it // easier to reason about their origin. - if (flags & TypeFlags.String) typeSet.containsString = true; - if (flags & TypeFlags.Number) typeSet.containsNumber = true; - if (flags & TypeFlags.ESSymbol) typeSet.containsESSymbol = true; - if (flags & TypeFlags.StringOrNumberLiteralOrUnique) typeSet.containsLiteralOrUniqueESSymbol = true; + if (flags & TypeFlags.String) includes |= TypeIncludes.String; + if (flags & TypeFlags.Number) includes |= TypeIncludes.Number; + if (flags & TypeFlags.ESSymbol) includes |= TypeIncludes.ESSymbol; + if (flags & TypeFlags.StringOrNumberLiteralOrUnique) includes |= TypeIncludes.LiteralOrUniqueESSymbol; const len = typeSet.length; const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); if (index < 0) { @@ -7489,14 +7491,16 @@ namespace ts { } } } + return includes; } // Add the given types to the given type set. Order is preserved, duplicates are removed, // and nested types of the given kind are flattened into the set. - function addTypesToUnion(typeSet: TypeSet, types: Type[]) { + function addTypesToUnion(typeSet: Type[], includes: TypeIncludes, types: Type[]): TypeIncludes { for (const type of types) { - addTypeToUnion(typeSet, type); + includes = addTypeToUnion(typeSet, includes, type); } + return includes; } function containsIdenticalType(types: Type[], type: Type) { @@ -7520,7 +7524,7 @@ namespace ts { return false; } - function isSetOfLiteralsFromSameEnum(types: TypeSet): boolean { + function isSetOfLiteralsFromSameEnum(types: Type[]): boolean { const first = types[0]; if (first.flags & TypeFlags.EnumLiteral) { const firstEnum = getParentOfSymbol(first.symbol); @@ -7536,7 +7540,7 @@ namespace ts { return false; } - function removeSubtypes(types: TypeSet) { + function removeSubtypes(types: Type[]) { if (types.length === 0 || isSetOfLiteralsFromSameEnum(types)) { return; } @@ -7549,15 +7553,15 @@ namespace ts { } } - function removeRedundantLiteralTypes(types: TypeSet) { + function removeRedundantLiteralTypes(types: Type[], includes: TypeIncludes) { let i = types.length; while (i > 0) { i--; const t = types[i]; const remove = - t.flags & TypeFlags.StringLiteral && types.containsString || - t.flags & TypeFlags.NumberLiteral && types.containsNumber || - t.flags & TypeFlags.UniqueESSymbol && types.containsESSymbol || + t.flags & TypeFlags.StringLiteral && includes & TypeIncludes.String || + t.flags & TypeFlags.NumberLiteral && includes & TypeIncludes.Number || + t.flags & TypeFlags.UniqueESSymbol && includes & TypeIncludes.ESSymbol || t.flags & TypeFlags.StringOrNumberLiteral && t.flags & TypeFlags.FreshLiteral && containsType(types, (t).regularType); if (remove) { orderedRemoveItemAt(types, i); @@ -7579,15 +7583,15 @@ namespace ts { if (types.length === 1) { return types[0]; } - const typeSet = [] as TypeSet; - addTypesToUnion(typeSet, types); - if (typeSet.containsAny) { + const typeSet: Type[] = []; + const includes = addTypesToUnion(typeSet, 0, types); + if (includes & TypeIncludes.Any) { return anyType; } switch (unionReduction) { case UnionReduction.Literal: - if (typeSet.containsLiteralOrUniqueESSymbol) { - removeRedundantLiteralTypes(typeSet); + if (includes & TypeIncludes.LiteralOrUniqueESSymbol) { + removeRedundantLiteralTypes(typeSet, includes); } break; case UnionReduction.Subtype: @@ -7595,8 +7599,8 @@ namespace ts { break; } if (typeSet.length === 0) { - return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType : - typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType : + return includes & TypeIncludes.Null ? includes & TypeIncludes.NonWideningType ? nullType : nullWideningType : + includes & TypeIncludes.Undefined ? includes & TypeIncludes.NonWideningType ? undefinedType : undefinedWideningType : neverType; } return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments); @@ -7674,39 +7678,42 @@ namespace ts { return links.resolvedType; } - function addTypeToIntersection(typeSet: TypeSet, type: Type) { - if (type.flags & TypeFlags.Intersection) { - addTypesToIntersection(typeSet, (type).types); + function addTypeToIntersection(typeSet: Type[], includes: TypeIncludes, type: Type) { + const flags = type.flags; + if (flags & TypeFlags.Intersection) { + includes = addTypesToIntersection(typeSet, includes, (type).types); } - else if (type.flags & TypeFlags.Any) { - typeSet.containsAny = true; + else if (flags & TypeFlags.Any) { + includes |= TypeIncludes.Any; } - else if (type.flags & TypeFlags.Never) { - typeSet.containsNever = true; + else if (flags & TypeFlags.Never) { + includes |= TypeIncludes.Never; } else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) { - typeSet.containsEmptyObject = true; + includes |= TypeIncludes.EmptyObject; } - else if ((strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { - if (type.flags & TypeFlags.Object) { - typeSet.containsObjectType = true; + else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { + if (flags & TypeFlags.Object) { + includes |= TypeIncludes.ObjectType; } - if (type.flags & TypeFlags.Union && typeSet.unionIndex === undefined) { - typeSet.unionIndex = typeSet.length; + if (flags & TypeFlags.Union) { + includes |= TypeIncludes.Union; } - if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && + if (!(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) { typeSet.push(type); } } + return includes; } // Add the given types to the given type set. Order is preserved, freshness is removed from literal // types, duplicates are removed, and nested types of the given kind are flattened into the set. - function addTypesToIntersection(typeSet: TypeSet, types: Type[]) { + function addTypesToIntersection(typeSet: Type[], includes: TypeIncludes, types: Type[]) { for (const type of types) { - addTypeToIntersection(typeSet, getRegularTypeOfLiteralType(type)); + includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type)); } + return includes; } // We normalize combinations of intersection and union types based on the distributive property of the '&' @@ -7723,27 +7730,27 @@ namespace ts { if (types.length === 0) { return emptyObjectType; } - const typeSet = [] as TypeSet; - addTypesToIntersection(typeSet, types); - if (typeSet.containsNever) { + const typeSet: Type[] = []; + const includes = addTypesToIntersection(typeSet, 0, types); + if (includes & TypeIncludes.Never) { return neverType; } - if (typeSet.containsAny) { + if (includes & TypeIncludes.Any) { return anyType; } - if (typeSet.containsEmptyObject && !typeSet.containsObjectType) { + if (includes & TypeIncludes.EmptyObject && !(includes & TypeIncludes.ObjectType)) { typeSet.push(emptyObjectType); } if (typeSet.length === 1) { return typeSet[0]; } - const unionIndex = typeSet.unionIndex; - if (unionIndex !== undefined) { + if (includes & TypeIncludes.Union) { // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain. + const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0); const unionType = typeSet[unionIndex]; return getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))), - UnionReduction.Literal, aliasSymbol, aliasTypeArguments); + UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } const id = getTypeListId(typeSet); let type = intersectionTypes.get(id); From 06c28ea69bf48ffd057f1a01f97bdeef3d76ff39 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 2 Feb 2018 07:48:21 -0800 Subject: [PATCH 35/42] Initialize more common properties in Symbol constructor --- src/compiler/core.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 2966582cb39..2b56a95b061 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2772,6 +2772,10 @@ namespace ts { this.flags = flags; this.escapedName = name; this.declarations = undefined; + this.valueDeclaration = undefined; + this.id = undefined; + this.mergeId = undefined; + this.parent = undefined; } function Type(this: Type, checker: TypeChecker, flags: TypeFlags) { From b3ec8cce00f2444ca6e7ba2582793fa1cdd5f54f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 2 Feb 2018 10:11:50 -0800 Subject: [PATCH 36/42] Leverage existing function for choosing spread validity (#21564) --- src/compiler/checker.ts | 2 +- .../reference/esModuleIntersectionCrash.js | 27 ++++++++++++++ .../esModuleIntersectionCrash.symbols | 37 +++++++++++++++++++ .../reference/esModuleIntersectionCrash.types | 37 +++++++++++++++++++ .../compiler/esModuleIntersectionCrash.ts | 12 ++++++ 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/esModuleIntersectionCrash.js create mode 100644 tests/baselines/reference/esModuleIntersectionCrash.symbols create mode 100644 tests/baselines/reference/esModuleIntersectionCrash.types create mode 100644 tests/cases/compiler/esModuleIntersectionCrash.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f6a9a90987a..062ff73b165 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17603,7 +17603,7 @@ namespace ts { const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); anonymousSymbol.type = defaultContainingObject; - synthType.syntheticType = (type.flags & TypeFlags.StructuredType && type.symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable)) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*propegatedFlags*/ 0) : defaultContainingObject; + synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*propegatedFlags*/ 0) : defaultContainingObject; } else { synthType.syntheticType = type; diff --git a/tests/baselines/reference/esModuleIntersectionCrash.js b/tests/baselines/reference/esModuleIntersectionCrash.js new file mode 100644 index 00000000000..a8f6ed5c014 --- /dev/null +++ b/tests/baselines/reference/esModuleIntersectionCrash.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/esModuleIntersectionCrash.ts] //// + +//// [mod.d.ts] +export = modObj; +declare const modObj: modObj.A & modObj.B; +declare namespace modObj { + interface A { (): void; a: string; } + interface B { (x: string): void; b: string; } +} +//// [idx.ts] +import * as mod from "./mod"; +mod.a; +mod.b; + +//// [idx.js] +"use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +exports.__esModule = true; +var mod = __importStar(require("./mod")); +mod.a; +mod.b; diff --git a/tests/baselines/reference/esModuleIntersectionCrash.symbols b/tests/baselines/reference/esModuleIntersectionCrash.symbols new file mode 100644 index 00000000000..f2e34f71dae --- /dev/null +++ b/tests/baselines/reference/esModuleIntersectionCrash.symbols @@ -0,0 +1,37 @@ +=== tests/cases/compiler/mod.d.ts === +export = modObj; +>modObj : Symbol(modObj, Decl(mod.d.ts, 1, 13), Decl(mod.d.ts, 1, 42)) + +declare const modObj: modObj.A & modObj.B; +>modObj : Symbol(modObj, Decl(mod.d.ts, 1, 13), Decl(mod.d.ts, 1, 42)) +>modObj : Symbol(modObj, Decl(mod.d.ts, 1, 13), Decl(mod.d.ts, 1, 42)) +>A : Symbol(modObj.A, Decl(mod.d.ts, 2, 26)) +>modObj : Symbol(modObj, Decl(mod.d.ts, 1, 13), Decl(mod.d.ts, 1, 42)) +>B : Symbol(modObj.B, Decl(mod.d.ts, 3, 40)) + +declare namespace modObj { +>modObj : Symbol(modObj, Decl(mod.d.ts, 1, 13), Decl(mod.d.ts, 1, 42)) + + interface A { (): void; a: string; } +>A : Symbol(A, Decl(mod.d.ts, 2, 26)) +>a : Symbol(A.a, Decl(mod.d.ts, 3, 27)) + + interface B { (x: string): void; b: string; } +>B : Symbol(B, Decl(mod.d.ts, 3, 40)) +>x : Symbol(x, Decl(mod.d.ts, 4, 19)) +>b : Symbol(B.b, Decl(mod.d.ts, 4, 36)) +} +=== tests/cases/compiler/idx.ts === +import * as mod from "./mod"; +>mod : Symbol(mod, Decl(idx.ts, 0, 6)) + +mod.a; +>mod.a : Symbol(mod.A.a, Decl(mod.d.ts, 3, 27)) +>mod : Symbol(mod, Decl(idx.ts, 0, 6)) +>a : Symbol(mod.A.a, Decl(mod.d.ts, 3, 27)) + +mod.b; +>mod.b : Symbol(mod.B.b, Decl(mod.d.ts, 4, 36)) +>mod : Symbol(mod, Decl(idx.ts, 0, 6)) +>b : Symbol(mod.B.b, Decl(mod.d.ts, 4, 36)) + diff --git a/tests/baselines/reference/esModuleIntersectionCrash.types b/tests/baselines/reference/esModuleIntersectionCrash.types new file mode 100644 index 00000000000..f5de07acc42 --- /dev/null +++ b/tests/baselines/reference/esModuleIntersectionCrash.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/mod.d.ts === +export = modObj; +>modObj : modObj.A & modObj.B + +declare const modObj: modObj.A & modObj.B; +>modObj : modObj.A & modObj.B +>modObj : any +>A : modObj.A +>modObj : any +>B : modObj.B + +declare namespace modObj { +>modObj : A & B + + interface A { (): void; a: string; } +>A : A +>a : string + + interface B { (x: string): void; b: string; } +>B : B +>x : string +>b : string +} +=== tests/cases/compiler/idx.ts === +import * as mod from "./mod"; +>mod : { default: mod.A & mod.B; a: string; b: string; } + +mod.a; +>mod.a : string +>mod : { default: mod.A & mod.B; a: string; b: string; } +>a : string + +mod.b; +>mod.b : string +>mod : { default: mod.A & mod.B; a: string; b: string; } +>b : string + diff --git a/tests/cases/compiler/esModuleIntersectionCrash.ts b/tests/cases/compiler/esModuleIntersectionCrash.ts new file mode 100644 index 00000000000..d25b25b0efc --- /dev/null +++ b/tests/cases/compiler/esModuleIntersectionCrash.ts @@ -0,0 +1,12 @@ +// @esModuleInterop: true +// @filename: mod.d.ts +export = modObj; +declare const modObj: modObj.A & modObj.B; +declare namespace modObj { + interface A { (): void; a: string; } + interface B { (x: string): void; b: string; } +} +// @filename: idx.ts +import * as mod from "./mod"; +mod.a; +mod.b; \ No newline at end of file From 78f217bdd63bd1e488e5060c5a9f18a5eeeaddf1 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 2 Feb 2018 10:49:34 -0800 Subject: [PATCH 37/42] Assert `exportingModuleSymbol` is defined (#21340) * Assert `exportingModuleSymbol` is defined * Add assert message * Add message in both places --- src/compiler/core.ts | 5 +++++ src/services/findAllReferences.ts | 2 +- src/services/importTracker.ts | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c2ede12345f..ec8860a19d9 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2882,6 +2882,11 @@ namespace ts { throw e; } + export function assertDefined(value: T | null | undefined, message?: string): T { + assert(value !== undefined && value !== null, message); + return value; + } + export function assertNever(member: never, message?: string, stackCrawlMark?: AnyFunction): never { return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 31a0702bb82..6869e7331c3 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -366,7 +366,7 @@ namespace ts.FindAllReferences.Core { if (node.kind === SyntaxKind.DefaultKeyword) { addReference(node, symbol, node, state); - searchForImportsOfExport(node, symbol, { exportingModuleSymbol: symbol.parent, exportKind: ExportKind.Default }, state); + searchForImportsOfExport(node, symbol, { exportingModuleSymbol: Debug.assertDefined(symbol.parent, "Expected export symbol to have a parent"), exportKind: ExportKind.Default }, state); } else { const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: populateSearchSymbolSet(symbol, node, checker, options.implementations) }); diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index a8f724cb4be..e0ad6f40d75 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -491,8 +491,7 @@ namespace ts.FindAllReferences { function getExportAssignmentExport(ex: ExportAssignment): ExportedSymbol { // Get the symbol for the `export =` node; its parent is the module it's the export of. - const exportingModuleSymbol = ex.symbol.parent; - Debug.assert(!!exportingModuleSymbol); + const exportingModuleSymbol = Debug.assertDefined(ex.symbol.parent, "Expected export symbol to have a parent"); const exportKind = ex.isExportEquals ? ExportKind.ExportEquals : ExportKind.Default; return { kind: ImportExport.Export, symbol, exportInfo: { exportingModuleSymbol, exportKind } }; } From 567fba251b62f9085681357b74bc615da82189bf Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 2 Feb 2018 13:03:18 -0800 Subject: [PATCH 38/42] Support exclamationToken in updateProperty and createProperty (#21577) --- src/compiler/factory.ts | 12 +++++++----- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++-- tests/baselines/reference/api/typescript.d.ts | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index c622ddfb2bf..7970bb1b242 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -349,14 +349,15 @@ namespace ts { decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, - questionToken: QuestionToken | undefined, + questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { const node = createSynthesizedNode(SyntaxKind.PropertyDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); - node.questionToken = questionToken; + node.questionToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.QuestionToken ? questionOrExclamationToken : undefined; + node.exclamationToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.ExclamationToken ? questionOrExclamationToken : undefined; node.type = type; node.initializer = initializer; return node; @@ -367,16 +368,17 @@ namespace ts { decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, - questionToken: QuestionToken | undefined, + questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name - || node.questionToken !== questionToken + || node.questionToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.QuestionToken ? questionOrExclamationToken : undefined) + || node.exclamationToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.ExclamationToken ? questionOrExclamationToken : undefined) || node.type !== type || node.initializer !== initializer - ? updateNode(createProperty(decorators, modifiers, name, questionToken, type, initializer), node) + ? updateNode(createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node) : node; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 921cff852d4..09cf8199ddb 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3427,8 +3427,8 @@ declare namespace ts { function updateDecorator(node: Decorator, expression: Expression): Decorator; function createPropertySignature(modifiers: ReadonlyArray | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; function updatePropertySignature(node: PropertySignature, modifiers: ReadonlyArray | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; - function createProperty(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; - function updateProperty(node: PropertyDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + function createProperty(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + function updateProperty(node: PropertyDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; function createMethodSignature(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature; function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined): MethodSignature; function createMethod(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 36094eeaa9e..f8ffc686008 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3374,8 +3374,8 @@ declare namespace ts { function updateDecorator(node: Decorator, expression: Expression): Decorator; function createPropertySignature(modifiers: ReadonlyArray | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; function updatePropertySignature(node: PropertySignature, modifiers: ReadonlyArray | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; - function createProperty(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; - function updateProperty(node: PropertyDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + function createProperty(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + function updateProperty(node: PropertyDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; function createMethodSignature(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature; function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined): MethodSignature; function createMethod(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; From 2c3b69336f0701e4c6d7a45a58a318936d837070 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 2 Feb 2018 13:17:39 -0800 Subject: [PATCH 39/42] Collect import helper needs during module info gathering (#21567) * Collect import helper needs during module info gathering * Add tests for other forms that trigger import helpers --- src/compiler/factory.ts | 4 +- src/compiler/transformers/module/module.ts | 25 +------- src/compiler/transformers/utilities.ts | 30 ++++++++- .../reference/esModuleInteropTslibHelpers.js | 64 +++++++++++++++++++ .../esModuleInteropTslibHelpers.symbols | 45 +++++++++++++ .../esModuleInteropTslibHelpers.types | 61 ++++++++++++++++++ .../compiler/esModuleInteropTslibHelpers.ts | 21 ++++++ 7 files changed, 224 insertions(+), 26 deletions(-) create mode 100644 tests/baselines/reference/esModuleInteropTslibHelpers.js create mode 100644 tests/baselines/reference/esModuleInteropTslibHelpers.symbols create mode 100644 tests/baselines/reference/esModuleInteropTslibHelpers.types create mode 100644 tests/cases/compiler/esModuleInteropTslibHelpers.ts diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 7970bb1b242..32f6877a152 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -4295,7 +4295,7 @@ namespace ts { return emitNode && emitNode.externalHelpersModuleName; } - export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean) { + export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) { if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) { const externalHelpersModuleName = getExternalHelpersModuleName(node); if (externalHelpersModuleName) { @@ -4303,7 +4303,7 @@ namespace ts { } const moduleKind = getEmitModuleKind(compilerOptions); - let create = hasExportStarsToExportValues + let create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault)) && moduleKind !== ModuleKind.System && moduleKind !== ModuleKind.ES2015 && moduleKind !== ModuleKind.ESNext; diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index aabc2bc45c1..2c75964d616 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -690,36 +690,15 @@ namespace ts { return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); } - function getNamedImportCount(node: ImportDeclaration) { - if (!(node.importClause && node.importClause.namedBindings)) return 0; - const names = node.importClause.namedBindings; - if (!names) return 0; - if (!isNamedImports(names)) return 0; - return names.elements.length; - } - - function containsDefaultReference(node: NamedImportBindings) { - if (!node) return false; - if (!isNamedImports(node)) return false; - return some(node.elements, isNamedDefaultReference); - } - - function isNamedDefaultReference(e: ImportSpecifier) { - return e.propertyName && e.propertyName.escapedText === InternalSymbolName.Default; - } - function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) { if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { return innerExpr; } - const nameCount = getNamedImportCount(node); - const hasDefault = nameCount > 0 ? containsDefaultReference(node.importClause.namedBindings) : undefined; - - if (getNamespaceDeclarationNode(node) || (nameCount > 1 && hasDefault)) { + if (getImportNeedsImportStarHelper(node)) { context.requestEmitHelper(importStarHelper); return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]); } - if (isDefaultImport(node) || (nameCount === 1 && hasDefault)) { + if (getImportNeedsImportDefaultHelper(node)) { context.requestEmitHelper(importDefaultHelper); return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]); } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 15e91d755ca..9267a239bb4 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -15,6 +15,32 @@ namespace ts { hasExportStarsToExportValues: boolean; // whether this module contains export* } + function getNamedImportCount(node: ImportDeclaration) { + if (!(node.importClause && node.importClause.namedBindings)) return 0; + const names = node.importClause.namedBindings; + if (!names) return 0; + if (!isNamedImports(names)) return 0; + return names.elements.length; + } + + function containsDefaultReference(node: NamedImportBindings) { + if (!node) return false; + if (!isNamedImports(node)) return false; + return some(node.elements, isNamedDefaultReference); + } + + function isNamedDefaultReference(e: ImportSpecifier) { + return e.propertyName && e.propertyName.escapedText === InternalSymbolName.Default; + } + + export function getImportNeedsImportStarHelper(node: ImportDeclaration) { + return !!getNamespaceDeclarationNode(node) || (getNamedImportCount(node) > 1 && containsDefaultReference(node.importClause.namedBindings)); + } + + export function getImportNeedsImportDefaultHelper(node: ImportDeclaration) { + return isDefaultImport(node) || (getNamedImportCount(node) === 1 && containsDefaultReference(node.importClause.namedBindings)); + } + export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo { const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = []; const exportSpecifiers = createMultiMap(); @@ -24,6 +50,7 @@ namespace ts { let hasExportDefault = false; let exportEquals: ExportAssignment = undefined; let hasExportStarsToExportValues = false; + let hasImportStarOrImportDefault = false; for (const node of sourceFile.statements) { switch (node.kind) { @@ -33,6 +60,7 @@ namespace ts { // import * as x from "mod" // import { x, y } from "mod" externalImports.push(node); + hasImportStarOrImportDefault = getImportNeedsImportStarHelper(node) || getImportNeedsImportDefaultHelper(node); break; case SyntaxKind.ImportEqualsDeclaration: @@ -135,7 +163,7 @@ namespace ts { } } - const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues); + const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStarOrImportDefault); const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, diff --git a/tests/baselines/reference/esModuleInteropTslibHelpers.js b/tests/baselines/reference/esModuleInteropTslibHelpers.js new file mode 100644 index 00000000000..a844bd40cfb --- /dev/null +++ b/tests/baselines/reference/esModuleInteropTslibHelpers.js @@ -0,0 +1,64 @@ +//// [tests/cases/compiler/esModuleInteropTslibHelpers.ts] //// + +//// [refs.d.ts] +declare module "path"; +//// [file.ts] +import path from "path"; +path.resolve("", "../"); +export class Foo { } +//// [file2.ts] +import * as path from "path"; +path.resolve("", "../"); +export class Foo2 { } +//// [file3.ts] +import {default as resolve} from "path"; +resolve("", "../"); +export class Foo3 { } +//// [file4.ts] +import {Bar, default as resolve} from "path"; +resolve("", "../"); +export { Bar } + +//// [file.js] +"use strict"; +exports.__esModule = true; +var tslib_1 = require("tslib"); +var path_1 = tslib_1.__importDefault(require("path")); +path_1["default"].resolve("", "../"); +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); +exports.Foo = Foo; +//// [file2.js] +"use strict"; +exports.__esModule = true; +var tslib_1 = require("tslib"); +var path = tslib_1.__importStar(require("path")); +path.resolve("", "../"); +var Foo2 = /** @class */ (function () { + function Foo2() { + } + return Foo2; +}()); +exports.Foo2 = Foo2; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var tslib_1 = require("tslib"); +var path_1 = tslib_1.__importDefault(require("path")); +path_1["default"]("", "../"); +var Foo3 = /** @class */ (function () { + function Foo3() { + } + return Foo3; +}()); +exports.Foo3 = Foo3; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var tslib_1 = require("tslib"); +var path_1 = tslib_1.__importStar(require("path")); +exports.Bar = path_1.Bar; +path_1["default"]("", "../"); diff --git a/tests/baselines/reference/esModuleInteropTslibHelpers.symbols b/tests/baselines/reference/esModuleInteropTslibHelpers.symbols new file mode 100644 index 00000000000..d6bf19071bc --- /dev/null +++ b/tests/baselines/reference/esModuleInteropTslibHelpers.symbols @@ -0,0 +1,45 @@ +=== tests/cases/compiler/refs.d.ts === +declare module "path"; +No type information for this code.=== tests/cases/compiler/file.ts === +import path from "path"; +>path : Symbol(path, Decl(file.ts, 0, 6)) + +path.resolve("", "../"); +>path : Symbol(path, Decl(file.ts, 0, 6)) + +export class Foo { } +>Foo : Symbol(Foo, Decl(file.ts, 1, 24)) + +=== tests/cases/compiler/file2.ts === +import * as path from "path"; +>path : Symbol(path, Decl(file2.ts, 0, 6)) + +path.resolve("", "../"); +>path : Symbol(path, Decl(file2.ts, 0, 6)) + +export class Foo2 { } +>Foo2 : Symbol(Foo2, Decl(file2.ts, 1, 24)) + +=== tests/cases/compiler/file3.ts === +import {default as resolve} from "path"; +>default : Symbol(resolve, Decl(file3.ts, 0, 8)) +>resolve : Symbol(resolve, Decl(file3.ts, 0, 8)) + +resolve("", "../"); +>resolve : Symbol(resolve, Decl(file3.ts, 0, 8)) + +export class Foo3 { } +>Foo3 : Symbol(Foo3, Decl(file3.ts, 1, 19)) + +=== tests/cases/compiler/file4.ts === +import {Bar, default as resolve} from "path"; +>Bar : Symbol(Bar, Decl(file4.ts, 0, 8)) +>default : Symbol(resolve, Decl(file4.ts, 0, 12)) +>resolve : Symbol(resolve, Decl(file4.ts, 0, 12)) + +resolve("", "../"); +>resolve : Symbol(resolve, Decl(file4.ts, 0, 12)) + +export { Bar } +>Bar : Symbol(Bar, Decl(file4.ts, 2, 8)) + diff --git a/tests/baselines/reference/esModuleInteropTslibHelpers.types b/tests/baselines/reference/esModuleInteropTslibHelpers.types new file mode 100644 index 00000000000..e0d6ac24f8f --- /dev/null +++ b/tests/baselines/reference/esModuleInteropTslibHelpers.types @@ -0,0 +1,61 @@ +=== tests/cases/compiler/refs.d.ts === +declare module "path"; +No type information for this code.=== tests/cases/compiler/file.ts === +import path from "path"; +>path : any + +path.resolve("", "../"); +>path.resolve("", "../") : any +>path.resolve : any +>path : any +>resolve : any +>"" : "" +>"../" : "../" + +export class Foo { } +>Foo : Foo + +=== tests/cases/compiler/file2.ts === +import * as path from "path"; +>path : any + +path.resolve("", "../"); +>path.resolve("", "../") : any +>path.resolve : any +>path : any +>resolve : any +>"" : "" +>"../" : "../" + +export class Foo2 { } +>Foo2 : Foo2 + +=== tests/cases/compiler/file3.ts === +import {default as resolve} from "path"; +>default : any +>resolve : any + +resolve("", "../"); +>resolve("", "../") : any +>resolve : any +>"" : "" +>"../" : "../" + +export class Foo3 { } +>Foo3 : Foo3 + +=== tests/cases/compiler/file4.ts === +import {Bar, default as resolve} from "path"; +>Bar : any +>default : any +>resolve : any + +resolve("", "../"); +>resolve("", "../") : any +>resolve : any +>"" : "" +>"../" : "../" + +export { Bar } +>Bar : any + diff --git a/tests/cases/compiler/esModuleInteropTslibHelpers.ts b/tests/cases/compiler/esModuleInteropTslibHelpers.ts new file mode 100644 index 00000000000..a485ae8d2af --- /dev/null +++ b/tests/cases/compiler/esModuleInteropTslibHelpers.ts @@ -0,0 +1,21 @@ +// @esModuleInterop: true +// @importHelpers: true +// @noEmitHelpers: true +// @filename: refs.d.ts +declare module "path"; +// @filename: file.ts +import path from "path"; +path.resolve("", "../"); +export class Foo { } +// @filename: file2.ts +import * as path from "path"; +path.resolve("", "../"); +export class Foo2 { } +// @filename: file3.ts +import {default as resolve} from "path"; +resolve("", "../"); +export class Foo3 { } +// @filename: file4.ts +import {Bar, default as resolve} from "path"; +resolve("", "../"); +export { Bar } \ No newline at end of file From be0fcd5174fbab4be792f9687256138a8a8b4647 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 2 Feb 2018 13:20:40 -0800 Subject: [PATCH 40/42] Array.concat now takes ConcatArray, not ReadonlyArray (#21462) * Overloads in Array.concat now handle ReadonlyArray Previously it was union types, which is slower. * Make arrayConcat3 test stricter * Switch to InputArray instead of adding overloads * Update baselines * Update baselines correctly * Rename to ConcatArray and add slice method Should make it, respectively, easier to understand this specific type and harder to satisfy it by mistake. --- src/lib/es5.d.ts | 15 +++++-- tests/baselines/reference/arrayConcat2.types | 12 +++--- tests/baselines/reference/arrayConcat3.types | 4 +- .../baselines/reference/arrayConcatMap.types | 4 +- ...typeIsAssignableToReadonlyArray.errors.txt | 8 ++-- tests/baselines/reference/concatError.types | 8 ++-- tests/baselines/reference/concatTuples.types | 4 +- .../emitSkipsThisWithRestParameter.types | 4 +- .../intersectionTypeInference3.types | 4 +- .../iteratorSpreadInArray6.errors.txt | 40 ++++++------------- .../reference/iteratorSpreadInArray6.types | 4 +- .../reference/iteratorSpreadInArray7.types | 4 +- .../reference/parserRealSource4.types | 4 +- tests/baselines/reference/parserharness.types | 4 +- .../reference/restInvalidArgumentType.types | 2 +- .../reference/spreadInvalidArgumentType.types | 4 +- ...ymousTypeNotReferencingTypeParameter.types | 4 +- .../baselines/reference/underscoreTest1.types | 4 +- tests/cases/compiler/arrayConcat3.ts | 1 + 19 files changed, 63 insertions(+), 71 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 0f1a68de4c2..707f749e365 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -992,12 +992,12 @@ interface ReadonlyArray { * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: (T[] | ReadonlyArray)[]): T[]; + concat(...items: ConcatArray[]): T[]; /** * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: (T | T[] | ReadonlyArray)[]): T[]; + concat(...items: (T | ConcatArray)[]): T[]; /** * Adds all the elements of an array separated by the specified separator string. * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. @@ -1087,6 +1087,13 @@ interface ReadonlyArray { readonly [n: number]: T; } +interface ConcatArray { + readonly length: number; + readonly [n: number]: T; + join(separator?: string): string; + slice(start?: number, end?: number): T[]; +} + interface Array { /** * Gets or sets the length of the array. This is a number one higher than the highest element defined in an array. @@ -1113,12 +1120,12 @@ interface Array { * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: (T[] | ReadonlyArray)[]): T[]; + concat(...items: ConcatArray[]): T[]; /** * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: (T | T[] | ReadonlyArray)[]): T[]; + concat(...items: (T | ConcatArray)[]): T[]; /** * Adds all the elements of an array separated by the specified separator string. * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. diff --git a/tests/baselines/reference/arrayConcat2.types b/tests/baselines/reference/arrayConcat2.types index 2e33d4cd023..f1ca2a5f109 100644 --- a/tests/baselines/reference/arrayConcat2.types +++ b/tests/baselines/reference/arrayConcat2.types @@ -5,17 +5,17 @@ var a: string[] = []; a.concat("hello", 'world'); >a.concat("hello", 'world') : string[] ->a.concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>a.concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >a : string[] ->concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >"hello" : "hello" >'world' : "world" a.concat('Hello'); >a.concat('Hello') : string[] ->a.concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>a.concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >a : string[] ->concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >'Hello' : "Hello" var b = new Array(); @@ -25,8 +25,8 @@ var b = new Array(); b.concat('hello'); >b.concat('hello') : string[] ->b.concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>b.concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >b : string[] ->concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >'hello' : "hello" diff --git a/tests/baselines/reference/arrayConcat3.types b/tests/baselines/reference/arrayConcat3.types index 2bfbe09a176..33321c43217 100644 --- a/tests/baselines/reference/arrayConcat3.types +++ b/tests/baselines/reference/arrayConcat3.types @@ -25,9 +25,9 @@ function doStuff(a: Array>, b: Arrayb.concat(a) : Fn[] ->b.concat : { (...items: (Fn[] | ReadonlyArray>)[]): Fn[]; (...items: (Fn | Fn[] | ReadonlyArray>)[]): Fn[]; } +>b.concat : { (...items: ConcatArray>[]): Fn[]; (...items: (Fn | ConcatArray>)[]): Fn[]; } >b : Fn[] ->concat : { (...items: (Fn[] | ReadonlyArray>)[]): Fn[]; (...items: (Fn | Fn[] | ReadonlyArray>)[]): Fn[]; } +>concat : { (...items: ConcatArray>[]): Fn[]; (...items: (Fn | ConcatArray>)[]): Fn[]; } >a : Fn[] } diff --git a/tests/baselines/reference/arrayConcatMap.types b/tests/baselines/reference/arrayConcatMap.types index cbb30b8304a..ffc49e548a3 100644 --- a/tests/baselines/reference/arrayConcatMap.types +++ b/tests/baselines/reference/arrayConcatMap.types @@ -4,9 +4,9 @@ var x = [].concat([{ a: 1 }], [{ a: 2 }]) >[].concat([{ a: 1 }], [{ a: 2 }]) .map(b => b.a) : any[] >[].concat([{ a: 1 }], [{ a: 2 }]) .map : (callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any) => U[] >[].concat([{ a: 1 }], [{ a: 2 }]) : any[] ->[].concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>[].concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >[] : undefined[] ->concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >[{ a: 1 }] : { a: number; }[] >{ a: 1 } : { a: number; } >a : number diff --git a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt index 87c8b59ee1e..7ae20699c85 100644 --- a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt +++ b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt @@ -1,12 +1,12 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. Types of property 'concat' are incompatible. - Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. + Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. Type 'A[]' is not assignable to type 'B[]'. Type 'A' is not assignable to type 'B'. Property 'b' is missing in type 'A'. tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C' is not assignable to type 'ReadonlyArray'. Types of property 'concat' are incompatible. - Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. + Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. Type 'A[]' is not assignable to type 'B[]'. @@ -27,7 +27,7 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T ~~~ !!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. !!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. +!!! error TS2322: Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. !!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. !!! error TS2322: Type 'A' is not assignable to type 'B'. !!! error TS2322: Property 'b' is missing in type 'A'. @@ -39,6 +39,6 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T ~~~ !!! error TS2322: Type 'C' is not assignable to type 'ReadonlyArray'. !!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. +!!! error TS2322: Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. !!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. \ No newline at end of file diff --git a/tests/baselines/reference/concatError.types b/tests/baselines/reference/concatError.types index c7f07e4ea96..52f413b20b6 100644 --- a/tests/baselines/reference/concatError.types +++ b/tests/baselines/reference/concatError.types @@ -15,9 +15,9 @@ fa = fa.concat([0]); >fa = fa.concat([0]) : number[] >fa : number[] >fa.concat([0]) : number[] ->fa.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>fa.concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >fa : number[] ->concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >[0] : number[] >0 : 0 @@ -25,9 +25,9 @@ fa = fa.concat(0); >fa = fa.concat(0) : number[] >fa : number[] >fa.concat(0) : number[] ->fa.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>fa.concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >fa : number[] ->concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >0 : 0 diff --git a/tests/baselines/reference/concatTuples.types b/tests/baselines/reference/concatTuples.types index 46c06357b99..d85ee925570 100644 --- a/tests/baselines/reference/concatTuples.types +++ b/tests/baselines/reference/concatTuples.types @@ -10,9 +10,9 @@ ijs = ijs.concat([[3, 4], [5, 6]]); >ijs = ijs.concat([[3, 4], [5, 6]]) : [number, number][] >ijs : [number, number][] >ijs.concat([[3, 4], [5, 6]]) : [number, number][] ->ijs.concat : { (...items: ([number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; (...items: ([number, number] | [number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; } +>ijs.concat : { (...items: ConcatArray<[number, number]>[]): [number, number][]; (...items: ([number, number] | ConcatArray<[number, number]>)[]): [number, number][]; } >ijs : [number, number][] ->concat : { (...items: ([number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; (...items: ([number, number] | [number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; } +>concat : { (...items: ConcatArray<[number, number]>[]): [number, number][]; (...items: ([number, number] | ConcatArray<[number, number]>)[]): [number, number][]; } >[[3, 4], [5, 6]] : [number, number][] >[3, 4] : [number, number] >3 : 3 diff --git a/tests/baselines/reference/emitSkipsThisWithRestParameter.types b/tests/baselines/reference/emitSkipsThisWithRestParameter.types index 9d560a9e92f..9aa0e1fa55b 100644 --- a/tests/baselines/reference/emitSkipsThisWithRestParameter.types +++ b/tests/baselines/reference/emitSkipsThisWithRestParameter.types @@ -18,10 +18,10 @@ function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any >apply : (this: Function, thisArg: any, argArray?: any) => any >this : any >[ this ].concat(args) : any[] ->[ this ].concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>[ this ].concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >[ this ] : any[] >this : any ->concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >args : any[] }; diff --git a/tests/baselines/reference/intersectionTypeInference3.types b/tests/baselines/reference/intersectionTypeInference3.types index e6f411a603c..6239792f53d 100644 --- a/tests/baselines/reference/intersectionTypeInference3.types +++ b/tests/baselines/reference/intersectionTypeInference3.types @@ -32,13 +32,13 @@ declare const b: Set; const c1 = Array.from(a).concat(Array.from(b)); >c1 : Nominal<"A", string>[] >Array.from(a).concat(Array.from(b)) : Nominal<"A", string>[] ->Array.from(a).concat : { (...items: (Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; } +>Array.from(a).concat : { (...items: ConcatArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ConcatArray>)[]): Nominal<"A", string>[]; } >Array.from(a) : Nominal<"A", string>[] >Array.from : { (iterable: Iterable | ArrayLike): T[]; (iterable: Iterable | ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor >from : { (iterable: Iterable | ArrayLike): T[]; (iterable: Iterable | ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >a : Set> ->concat : { (...items: (Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; } +>concat : { (...items: ConcatArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ConcatArray>)[]): Nominal<"A", string>[]; } >Array.from(b) : Nominal<"A", string>[] >Array.from : { (iterable: Iterable | ArrayLike): T[]; (iterable: Iterable | ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor diff --git a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt index 17738ba06d5..4f547c59ed0 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt @@ -1,17 +1,9 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[] | ReadonlyArray'. - Type 'symbol[]' is not assignable to type 'ReadonlyArray'. - Types of property 'concat' are incompatible. - Type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }' is not assignable to type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }'. - Types of parameters 'items' and 'items' are incompatible. - Type 'number[] | ReadonlyArray' is not assignable to type 'symbol[] | ReadonlyArray'. - Type 'number[]' is not assignable to type 'symbol[] | ReadonlyArray'. - Type 'number[]' is not assignable to type 'ReadonlyArray'. - Types of property 'concat' are incompatible. - Type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }' is not assignable to type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }'. - Types of parameters 'items' and 'items' are incompatible. - Type 'symbol[] | ReadonlyArray' is not assignable to type 'number[] | ReadonlyArray'. - Type 'symbol[]' is not assignable to type 'number[] | ReadonlyArray'. - Type 'symbol[]' is not assignable to type 'ReadonlyArray'. +tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | ConcatArray'. + Type 'symbol[]' is not assignable to type 'ConcatArray'. + Types of property 'slice' are incompatible. + Type '(start?: number, end?: number) => symbol[]' is not assignable to type '(start?: number, end?: number) => number[]'. + Type 'symbol[]' is not assignable to type 'number[]'. + Type 'symbol' is not assignable to type 'number'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts (1 errors) ==== @@ -31,17 +23,9 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS234 var array: number[] = [0, 1]; array.concat([...new SymbolIterator]); ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[] | ReadonlyArray'. -!!! error TS2345: Type 'symbol[]' is not assignable to type 'ReadonlyArray'. -!!! error TS2345: Types of property 'concat' are incompatible. -!!! error TS2345: Type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }' is not assignable to type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }'. -!!! error TS2345: Types of parameters 'items' and 'items' are incompatible. -!!! error TS2345: Type 'number[] | ReadonlyArray' is not assignable to type 'symbol[] | ReadonlyArray'. -!!! error TS2345: Type 'number[]' is not assignable to type 'symbol[] | ReadonlyArray'. -!!! error TS2345: Type 'number[]' is not assignable to type 'ReadonlyArray'. -!!! error TS2345: Types of property 'concat' are incompatible. -!!! error TS2345: Type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }' is not assignable to type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }'. -!!! error TS2345: Types of parameters 'items' and 'items' are incompatible. -!!! error TS2345: Type 'symbol[] | ReadonlyArray' is not assignable to type 'number[] | ReadonlyArray'. -!!! error TS2345: Type 'symbol[]' is not assignable to type 'number[] | ReadonlyArray'. -!!! error TS2345: Type 'symbol[]' is not assignable to type 'ReadonlyArray'. \ No newline at end of file +!!! error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | ConcatArray'. +!!! error TS2345: Type 'symbol[]' is not assignable to type 'ConcatArray'. +!!! error TS2345: Types of property 'slice' are incompatible. +!!! error TS2345: Type '(start?: number, end?: number) => symbol[]' is not assignable to type '(start?: number, end?: number) => number[]'. +!!! error TS2345: Type 'symbol[]' is not assignable to type 'number[]'. +!!! error TS2345: Type 'symbol' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray6.types b/tests/baselines/reference/iteratorSpreadInArray6.types index dbf94611fab..3fa1720de14 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.types +++ b/tests/baselines/reference/iteratorSpreadInArray6.types @@ -38,9 +38,9 @@ var array: number[] = [0, 1]; array.concat([...new SymbolIterator]); >array.concat([...new SymbolIterator]) : any ->array.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>array.concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >array : number[] ->concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >[...new SymbolIterator] : symbol[] >...new SymbolIterator : symbol >new SymbolIterator : SymbolIterator diff --git a/tests/baselines/reference/iteratorSpreadInArray7.types b/tests/baselines/reference/iteratorSpreadInArray7.types index b0d9fbcc77c..65c34ae0a6e 100644 --- a/tests/baselines/reference/iteratorSpreadInArray7.types +++ b/tests/baselines/reference/iteratorSpreadInArray7.types @@ -35,9 +35,9 @@ var array: symbol[]; array.concat([...new SymbolIterator]); >array.concat([...new SymbolIterator]) : symbol[] ->array.concat : { (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; } +>array.concat : { (...items: ConcatArray[]): symbol[]; (...items: (symbol | ConcatArray)[]): symbol[]; } >array : symbol[] ->concat : { (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; } +>concat : { (...items: ConcatArray[]): symbol[]; (...items: (symbol | ConcatArray)[]): symbol[]; } >[...new SymbolIterator] : symbol[] >...new SymbolIterator : symbol >new SymbolIterator : SymbolIterator diff --git a/tests/baselines/reference/parserRealSource4.types b/tests/baselines/reference/parserRealSource4.types index cc16886c3d5..175ea23db81 100644 --- a/tests/baselines/reference/parserRealSource4.types +++ b/tests/baselines/reference/parserRealSource4.types @@ -424,14 +424,14 @@ module TypeScript { return this.primaryTable.getAllKeys().concat(this.secondaryTable.getAllKeys()); >this.primaryTable.getAllKeys().concat(this.secondaryTable.getAllKeys()) : string[] ->this.primaryTable.getAllKeys().concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>this.primaryTable.getAllKeys().concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >this.primaryTable.getAllKeys() : string[] >this.primaryTable.getAllKeys : () => string[] >this.primaryTable : IHashTable >this : this >primaryTable : IHashTable >getAllKeys : () => string[] ->concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } +>concat : { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } >this.secondaryTable.getAllKeys() : string[] >this.secondaryTable.getAllKeys : () => string[] >this.secondaryTable : IHashTable diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index cf08fc969ea..505cfe67c82 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -4868,9 +4868,9 @@ module Harness { >lines = lines.concat(v.file.lines) : any[] >lines : any[] >lines.concat(v.file.lines) : any[] ->lines.concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>lines.concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >lines : any[] ->concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >v.file.lines : string[] >v.file : WriterAggregator >v : { filename: string; file: WriterAggregator; } diff --git a/tests/baselines/reference/restInvalidArgumentType.types b/tests/baselines/reference/restInvalidArgumentType.types index 389e9a070aa..bad3f54c0e8 100644 --- a/tests/baselines/reference/restInvalidArgumentType.types +++ b/tests/baselines/reference/restInvalidArgumentType.types @@ -87,7 +87,7 @@ function f(p1: T, p2: T[]) { >p1 : T var {...r2} = p2; // OK ->r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: (T[] | ReadonlyArray)[]): T[]; concat(...items: (T | T[] | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ConcatArray[]): T[]; concat(...items: (T | ConcatArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >p2 : T[] var {...r3} = t; // Error, generic type paramter diff --git a/tests/baselines/reference/spreadInvalidArgumentType.types b/tests/baselines/reference/spreadInvalidArgumentType.types index 49d5bc96261..d85b974cc8b 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.types +++ b/tests/baselines/reference/spreadInvalidArgumentType.types @@ -89,8 +89,8 @@ function f(p1: T, p2: T[]) { >p1 : T var o2 = { ...p2 }; // OK ->o2 : { [x: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: (T[] | ReadonlyArray)[]): T[]; concat(...items: (T | T[] | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } ->{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: (T[] | ReadonlyArray)[]): T[]; concat(...items: (T | T[] | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>o2 : { [x: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ConcatArray[]): T[]; concat(...items: (T | ConcatArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ConcatArray[]): T[]; concat(...items: (T | ConcatArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >p2 : T[] var o3 = { ...t }; // Error, generic type paramter diff --git a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types index e4dc5df9449..56cded21345 100644 --- a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types +++ b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types @@ -348,9 +348,9 @@ class ListWrapper { >a : any[] >b : any[] >a.concat(b) : any[] ->a.concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>a.concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >a : any[] ->concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: ConcatArray[]): any[]; (...items: any[]): any[]; } >b : any[] static insert(dit: typeof ListWrapper, list: T[], index: number, value: T) { list.splice(index, 0, value); } diff --git a/tests/baselines/reference/underscoreTest1.types b/tests/baselines/reference/underscoreTest1.types index 111039994d5..101d7319553 100644 --- a/tests/baselines/reference/underscoreTest1.types +++ b/tests/baselines/reference/underscoreTest1.types @@ -124,9 +124,9 @@ var flat = _.reduceRight(list, (a, b) => a.concat(b), []); >a : number[] >b : number[] >a.concat(b) : number[] ->a.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>a.concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >a : number[] ->concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } +>concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } >b : number[] >[] : undefined[] diff --git a/tests/cases/compiler/arrayConcat3.ts b/tests/cases/compiler/arrayConcat3.ts index d66d488a20d..b0e4c4581dd 100644 --- a/tests/cases/compiler/arrayConcat3.ts +++ b/tests/cases/compiler/arrayConcat3.ts @@ -1,3 +1,4 @@ +// @strictFunctionTypes: true // TODO: remove lib hack when https://github.com/Microsoft/TypeScript/issues/20454 is fixed type Fn = (subj: U) => U function doStuff(a: Array>, b: Array>) { From b3cc65d18e752d7130b4dd928541b4d6d1e08dc3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 2 Feb 2018 18:21:01 -0800 Subject: [PATCH 41/42] Accept new user test baselines (#21576) --- .../reference/user/chrome-devtools-frontend.log | 10 +++++----- tests/baselines/reference/user/formik.log | 15 ++++++--------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index ebe4bb8edc1..11b61110d8d 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -9168,7 +9168,7 @@ node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(208,5): error TS2554: Expected 2-3 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(223,3): error TS2554: Expected 2-3 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(230,35): error TS2345: Argument of type '{ ranges: boolean; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(230,35): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. Property 'ecmaVersion' is incompatible with index signature. Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(258,14): error TS2339: Property 'parent' does not exist on type '{ start: number; end: number; type: string; body: any; declarations: any[]; properties: any[]; in...'. @@ -9235,7 +9235,7 @@ node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.j node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.js(401,27): error TS2339: Property 'Token' does not exist on type 'typeof (Anonymous class)'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.js(419,27): error TS2339: Property 'Tag' does not exist on type 'typeof (Anonymous class)'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.js(441,27): error TS2339: Property 'Element' does not exist on type 'typeof (Anonymous class)'. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(54,42): error TS2345: Argument of type '{ ranges: boolean; ecmaVersion: number; preserveParens: boolean; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(54,42): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; preserveParens: true; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. Property 'ecmaVersion' is incompatible with index signature. Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(60,21): error TS2694: Namespace 'Acorn' has no exported member 'TokenOrComment'. @@ -9286,10 +9286,10 @@ node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptForma node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(304,62): error TS2339: Property 'alternate' does not exist on type '{ start: number; end: number; type: string; body: any; declarations: any[]; properties: any[]; in...'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(306,23): error TS2339: Property 'consequent' does not exist on type '{ start: number; end: number; type: string; body: any; declarations: any[]; properties: any[]; in...'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(307,18): error TS2339: Property 'consequent' does not exist on type '{ start: number; end: number; type: string; body: any; declarations: any[]; properties: any[]; in...'. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(14,32): error TS2345: Argument of type '{ ranges: boolean; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(14,32): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. Property 'ecmaVersion' is incompatible with index signature. Type 'number' is not assignable to type 'boolean'. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(16,39): error TS2345: Argument of type '{ ranges: boolean; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(16,39): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. Property 'ecmaVersion' is incompatible with index signature. Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(19,53): error TS2339: Property 'computeLineEndings' does not exist on type 'string'. @@ -23432,7 +23432,7 @@ node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(32,18): error TS23 node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(39,16): error TS2339: Property '_observer' does not exist on type 'typeof (Anonymous class)'. node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(48,25): error TS2339: Property 'parentNodeOrShadowHost' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(56,19): error TS2339: Property 'parentNodeOrShadowHost' does not exist on type 'Node'. -node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(100,79): error TS2345: Argument of type '{ passive: boolean; capture: boolean; }' is not assignable to parameter of type 'boolean | EventListenerOptions'. +node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(100,79): error TS2345: Argument of type '{ passive: boolean; capture: false; }' is not assignable to parameter of type 'boolean | EventListenerOptions'. Object literal may only specify known properties, and 'passive' does not exist in type 'boolean | EventListenerOptions'. node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(108,19): error TS2551: Property '_scrollTop' does not exist on type 'Element'. Did you mean 'scrollTop'? node_modules/chrome-devtools-frontend/front_end/ui/XWidget.js(109,37): error TS2551: Property '_scrollTop' does not exist on type 'Element'. Did you mean 'scrollTop'? diff --git a/tests/baselines/reference/user/formik.log b/tests/baselines/reference/user/formik.log index 30767a636c9..52ea18319a2 100644 --- a/tests/baselines/reference/user/formik.log +++ b/tests/baselines/reference/user/formik.log @@ -1,15 +1,12 @@ Exit Code: 1 Standard output: -index.tsx(26,7): error TS2322: Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes, object>> & Readonly<{...'. - Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'Readonly>'. +index.tsx(26,7): error TS2322: Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes FormikErrors...' is not assignable to type 'Readonly & { initialValues: { email: string; p...'. Types of property 'onSubmit' are incompatible. - Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '(values: object, formikActions: FormikActions) => void'. -index.tsx(26,7): error TS2322: Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes, object>> & Readonly<{...'. - Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'Readonly>'. - Types of property 'onSubmit' are incompatible. - Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '(values: object, formikActions: FormikActions) => void'. - Types of parameters 'values' and 'values' are incompatible. - Type 'object' is not assignable to type 'Values'. + Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '((values: { email: string; password: string; }, formikActions: FormikActions<{ email: string; pas...'. + Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '(values: { email: string; password: string; }, formikActions: FormikActions<{ email: string; pass...'. + Types of parameters 'values' and 'values' are incompatible. + Type '{ email: string; password: string; }' is not assignable to type 'Values'. index.tsx(32,13): error TS2322: Type '{}' is not assignable to type 'FormikErrors'. Property 'email' is missing in type '{}'. index.tsx(33,21): error TS2339: Property 'email' does not exist on type 'Values'. From 89de4c9a3ab3f7f88a141f1529b77628204bff73 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 2 Feb 2018 18:44:54 -0800 Subject: [PATCH 42/42] Only apply global augmentations before globals are available (#21563) * Only apply global augmentations before globals are available * Add detailed comment explaining the split of global/nonglobal augmentations * Remove trailing whitespace --- src/compiler/checker.ts | 20 +++++- ...AugmentationDuringSyntheticDefaultCheck.js | 43 +++++++++++++ ...ntationDuringSyntheticDefaultCheck.symbols | 63 +++++++++++++++++++ ...mentationDuringSyntheticDefaultCheck.types | 63 +++++++++++++++++++ ...AugmentationDuringSyntheticDefaultCheck.ts | 34 ++++++++++ 5 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.js create mode 100644 tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.symbols create mode 100644 tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types create mode 100644 tests/cases/compiler/moduleAugmentationDuringSyntheticDefaultCheck.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5fd9aadf280..eccdef8fff6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25228,11 +25228,18 @@ namespace ts { } } + // We do global augmentations seperately from module augmentations (and before creating global types) because they + // 1. Affect global types. We won't have the correct global types until global augmentations are merged. Also, + // 2. Module augmentation instantiation requires creating the type of a module, which, in turn, can require + // checking for an export or property on the module (if export=) which, in turn, can fall back to the + // apparent type of the module - either globalObjectType or globalFunctionType - which wouldn't exist if we + // did module augmentations prior to finalizing the global types. if (augmentations) { - // merge module augmentations. + // merge _global_ module augmentations. // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed for (const list of augmentations) { for (const augmentation of list) { + if (!isGlobalScopeAugmentation(augmentation.parent as ModuleDeclaration)) continue; mergeModuleAugmentation(augmentation); } } @@ -25264,6 +25271,17 @@ namespace ts { globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1); anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; globalThisType = getGlobalTypeOrUndefined("ThisType" as __String, /*arity*/ 1); + + if (augmentations) { + // merge _nonglobal_ module augmentations. + // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed + for (const list of augmentations) { + for (const augmentation of list) { + if (isGlobalScopeAugmentation(augmentation.parent as ModuleDeclaration)) continue; + mergeModuleAugmentation(augmentation); + } + } + } } function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { diff --git a/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.js b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.js new file mode 100644 index 00000000000..56fc5806325 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.js @@ -0,0 +1,43 @@ +//// [tests/cases/compiler/moduleAugmentationDuringSyntheticDefaultCheck.ts] //// + +//// [index.d.ts] +declare function moment(): moment.Moment; +declare namespace moment { + interface Moment extends Object { + valueOf(): number; + } +} +export = moment; +//// [index.d.ts] +import * as moment from 'moment'; +export = moment; +declare module "moment" { + interface Moment { + tz(): string; + } +} +//// [idx.ts] +import * as _moment from "moment"; +declare module "moment" { + interface Moment { + strftime(pattern: string): string; + } +} +declare module "moment-timezone" { + interface Moment { + strftime(pattern: string): string; + } +} +//// [idx.test.ts] +/// + +import moment = require("moment-timezone"); + + +//// [idx.js] +"use strict"; +exports.__esModule = true; +//// [idx.test.js] +"use strict"; +/// +exports.__esModule = true; diff --git a/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.symbols b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.symbols new file mode 100644 index 00000000000..81d4012454e --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.symbols @@ -0,0 +1,63 @@ +=== tests/cases/compiler/idx.test.ts === +/// + +import moment = require("moment-timezone"); +>moment : Symbol(moment, Decl(idx.test.ts, 0, 0)) + +=== tests/cases/compiler/node_modules/moment/index.d.ts === +declare function moment(): moment.Moment; +>moment : Symbol(moment, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 41), Decl(idx.ts, 0, 34), Decl(index.d.ts, 1, 16)) +>moment : Symbol(moment, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 41)) +>Moment : Symbol(Moment, Decl(index.d.ts, 1, 26)) + +declare namespace moment { +>moment : Symbol(moment, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 41), Decl(idx.ts, 0, 34), Decl(index.d.ts, 1, 16)) + + interface Moment extends Object { +>Moment : Symbol(Moment, Decl(index.d.ts, 1, 26), Decl(idx.ts, 1, 25), Decl(idx.ts, 6, 34), Decl(index.d.ts, 2, 25)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + valueOf(): number; +>valueOf : Symbol(Moment.valueOf, Decl(index.d.ts, 2, 35)) + } +} +export = moment; +>moment : Symbol(moment, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 41)) + +=== tests/cases/compiler/node_modules/moment-timezone/index.d.ts === +import * as moment from 'moment'; +>moment : Symbol(moment, Decl(index.d.ts, 0, 6)) + +export = moment; +>moment : Symbol(moment, Decl(index.d.ts, 0, 6)) + +declare module "moment" { + interface Moment { +>Moment : Symbol(Moment, Decl(index.d.ts, 1, 26), Decl(idx.ts, 1, 25), Decl(idx.ts, 6, 34), Decl(index.d.ts, 2, 25)) + + tz(): string; +>tz : Symbol(Moment.tz, Decl(index.d.ts, 3, 22)) + } +} +=== tests/cases/compiler/idx.ts === +import * as _moment from "moment"; +>_moment : Symbol(_moment, Decl(idx.ts, 0, 6)) + +declare module "moment" { + interface Moment { +>Moment : Symbol(Moment, Decl(index.d.ts, 1, 26), Decl(idx.ts, 1, 25), Decl(idx.ts, 6, 34), Decl(index.d.ts, 2, 25)) + + strftime(pattern: string): string; +>strftime : Symbol(Moment.strftime, Decl(idx.ts, 2, 22), Decl(idx.ts, 7, 22)) +>pattern : Symbol(pattern, Decl(idx.ts, 3, 17)) + } +} +declare module "moment-timezone" { + interface Moment { +>Moment : Symbol(Moment, Decl(index.d.ts, 1, 26), Decl(idx.ts, 1, 25), Decl(idx.ts, 6, 34), Decl(index.d.ts, 2, 25)) + + strftime(pattern: string): string; +>strftime : Symbol(Moment.strftime, Decl(idx.ts, 2, 22), Decl(idx.ts, 7, 22)) +>pattern : Symbol(pattern, Decl(idx.ts, 8, 17)) + } +} diff --git a/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types new file mode 100644 index 00000000000..bfcf9a9e882 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types @@ -0,0 +1,63 @@ +=== tests/cases/compiler/idx.test.ts === +/// + +import moment = require("moment-timezone"); +>moment : { default: () => moment.Moment; } + +=== tests/cases/compiler/node_modules/moment/index.d.ts === +declare function moment(): moment.Moment; +>moment : () => Moment +>moment : any +>Moment : Moment + +declare namespace moment { +>moment : () => Moment + + interface Moment extends Object { +>Moment : Moment +>Object : Object + + valueOf(): number; +>valueOf : () => number + } +} +export = moment; +>moment : () => Moment + +=== tests/cases/compiler/node_modules/moment-timezone/index.d.ts === +import * as moment from 'moment'; +>moment : { default: () => moment.Moment; } + +export = moment; +>moment : { default: () => moment.Moment; } + +declare module "moment" { + interface Moment { +>Moment : Moment + + tz(): string; +>tz : () => string + } +} +=== tests/cases/compiler/idx.ts === +import * as _moment from "moment"; +>_moment : { default: () => _moment.Moment; } + +declare module "moment" { + interface Moment { +>Moment : Moment + + strftime(pattern: string): string; +>strftime : { (pattern: string): string; (pattern: string): string; } +>pattern : string + } +} +declare module "moment-timezone" { + interface Moment { +>Moment : Moment + + strftime(pattern: string): string; +>strftime : { (pattern: string): string; (pattern: string): string; } +>pattern : string + } +} diff --git a/tests/cases/compiler/moduleAugmentationDuringSyntheticDefaultCheck.ts b/tests/cases/compiler/moduleAugmentationDuringSyntheticDefaultCheck.ts new file mode 100644 index 00000000000..a0402aece9d --- /dev/null +++ b/tests/cases/compiler/moduleAugmentationDuringSyntheticDefaultCheck.ts @@ -0,0 +1,34 @@ +// @noImplicitReferences: true +// @esModuleInterop: true +// @filename: node_modules/moment/index.d.ts +declare function moment(): moment.Moment; +declare namespace moment { + interface Moment extends Object { + valueOf(): number; + } +} +export = moment; +// @filename: node_modules/moment-timezone/index.d.ts +import * as moment from 'moment'; +export = moment; +declare module "moment" { + interface Moment { + tz(): string; + } +} +// @filename: idx.ts +import * as _moment from "moment"; +declare module "moment" { + interface Moment { + strftime(pattern: string): string; + } +} +declare module "moment-timezone" { + interface Moment { + strftime(pattern: string): string; + } +} +// @filename: idx.test.ts +/// + +import moment = require("moment-timezone");