From cc2ea6849273498328f7c2e5ab2225275df012b6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 15 Apr 2019 15:06:44 -0700 Subject: [PATCH 01/16] Fix inference from enum object type to generic mapped type --- src/compiler/checker.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 72e85b3f8a81b..bfca2519eb783 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14960,12 +14960,10 @@ namespace ts { } // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. - const valueTypes = compact([ - getIndexTypeOfType(source, IndexKind.String), - getIndexTypeOfType(source, IndexKind.Number), - ...map(getPropertiesOfType(source), getTypeOfSymbol) - ]); - inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(target)); + const indexType = source.symbol && source.symbol.flags & SymbolFlags.Enum && getEnumKind(source.symbol) === EnumKind.Literal ? + undefined : getIndexTypeOfType(source, IndexKind.String) || getIndexTypeOfType(source, IndexKind.Number); + const sourcePropsType = indexType || getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)); + inferFromTypes(sourcePropsType, getTemplateTypeFromMappedType(target)); return true; } return false; From 83f3d2ee172705f5194906616c6ef924af4188d3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 15 Apr 2019 15:06:55 -0700 Subject: [PATCH 02/16] Add regression test --- tests/cases/compiler/mappedToToIndexSignatureInference.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/cases/compiler/mappedToToIndexSignatureInference.ts b/tests/cases/compiler/mappedToToIndexSignatureInference.ts index 6ce63ead59cb0..ee6f71a06166a 100644 --- a/tests/cases/compiler/mappedToToIndexSignatureInference.ts +++ b/tests/cases/compiler/mappedToToIndexSignatureInference.ts @@ -1,3 +1,11 @@ declare const fn: (object: { [Key in K]: V }) => object; declare const a: { [index: string]: number }; fn(a); + +// Repro from #30218 + +declare function enumValues(e: Record): V[]; + +enum E { A = 'foo', B = 'bar' } + +let x: E[] = enumValues(E); From 436f6067ac5d078558b96bb98f5199cf93f820a1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 15 Apr 2019 15:07:15 -0700 Subject: [PATCH 03/16] Accept new baselines --- .../mappedToToIndexSignatureInference.js | 14 +++++++++++ .../mappedToToIndexSignatureInference.symbols | 23 +++++++++++++++++++ .../mappedToToIndexSignatureInference.types | 19 +++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/tests/baselines/reference/mappedToToIndexSignatureInference.js b/tests/baselines/reference/mappedToToIndexSignatureInference.js index 2ea09b663a97b..03a24ab0ad98d 100644 --- a/tests/baselines/reference/mappedToToIndexSignatureInference.js +++ b/tests/baselines/reference/mappedToToIndexSignatureInference.js @@ -2,7 +2,21 @@ declare const fn: (object: { [Key in K]: V }) => object; declare const a: { [index: string]: number }; fn(a); + +// Repro from #30218 + +declare function enumValues(e: Record): V[]; + +enum E { A = 'foo', B = 'bar' } + +let x: E[] = enumValues(E); //// [mappedToToIndexSignatureInference.js] fn(a); +var E; +(function (E) { + E["A"] = "foo"; + E["B"] = "bar"; +})(E || (E = {})); +var x = enumValues(E); diff --git a/tests/baselines/reference/mappedToToIndexSignatureInference.symbols b/tests/baselines/reference/mappedToToIndexSignatureInference.symbols index d071f3f4c1cb7..d2d6f923f8706 100644 --- a/tests/baselines/reference/mappedToToIndexSignatureInference.symbols +++ b/tests/baselines/reference/mappedToToIndexSignatureInference.symbols @@ -16,3 +16,26 @@ fn(a); >fn : Symbol(fn, Decl(mappedToToIndexSignatureInference.ts, 0, 13)) >a : Symbol(a, Decl(mappedToToIndexSignatureInference.ts, 1, 13)) +// Repro from #30218 + +declare function enumValues(e: Record): V[]; +>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6)) +>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28)) +>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45)) +>e : Symbol(e, Decl(mappedToToIndexSignatureInference.ts, 6, 64)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28)) +>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45)) +>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45)) + +enum E { A = 'foo', B = 'bar' } +>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86)) +>A : Symbol(E.A, Decl(mappedToToIndexSignatureInference.ts, 8, 8)) +>B : Symbol(E.B, Decl(mappedToToIndexSignatureInference.ts, 8, 19)) + +let x: E[] = enumValues(E); +>x : Symbol(x, Decl(mappedToToIndexSignatureInference.ts, 10, 3)) +>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86)) +>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6)) +>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86)) + diff --git a/tests/baselines/reference/mappedToToIndexSignatureInference.types b/tests/baselines/reference/mappedToToIndexSignatureInference.types index 35b9b3565e009..21ab79e8e48b9 100644 --- a/tests/baselines/reference/mappedToToIndexSignatureInference.types +++ b/tests/baselines/reference/mappedToToIndexSignatureInference.types @@ -12,3 +12,22 @@ fn(a); >fn : (object: { [Key in K]: V; }) => object >a : { [index: string]: number; } +// Repro from #30218 + +declare function enumValues(e: Record): V[]; +>enumValues : (e: Record) => V[] +>e : Record + +enum E { A = 'foo', B = 'bar' } +>E : E +>A : E.A +>'foo' : "foo" +>B : E.B +>'bar' : "bar" + +let x: E[] = enumValues(E); +>x : E[] +>enumValues(E) : E[] +>enumValues : (e: Record) => V[] +>E : typeof E + From 9f5090cec7e1b27f0a030312b1d25d34daae7047 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 16 Apr 2019 12:22:42 -0700 Subject: [PATCH 04/16] Test case for #30891 --- src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/tsbuild/helpers.ts | 12 +- .../unittests/tsbuild/lateBoundSymbol.ts | 47 ++++++++ ...s-merged-and-contains-late-bound-member.js | 13 +++ ...s-merged-and-contains-late-bound-member.js | 106 ++++++++++++++++++ tests/projects/lateBoundSymbol/src/hkt.ts | 1 + tests/projects/lateBoundSymbol/src/main.ts | 11 ++ tests/projects/lateBoundSymbol/tsconfig.json | 9 ++ 8 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 src/testRunner/unittests/tsbuild/lateBoundSymbol.ts create mode 100644 tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js create mode 100644 tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js create mode 100644 tests/projects/lateBoundSymbol/src/hkt.ts create mode 100644 tests/projects/lateBoundSymbol/src/main.ts create mode 100644 tests/projects/lateBoundSymbol/tsconfig.json diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index d3ea4744e8a6f..6b73324e2f737 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -92,6 +92,7 @@ "unittests/tsbuild/amdModulesWithOut.ts", "unittests/tsbuild/emptyFiles.ts", "unittests/tsbuild/graphOrdering.ts", + "unittests/tsbuild/lateBoundSymbol.ts", "unittests/tsbuild/missingExtendedFile.ts", "unittests/tsbuild/outFile.ts", "unittests/tsbuild/referencesWithRootDirInParent.ts", diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 6915dd5d3b75b..589ba7a3021bf 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -285,8 +285,10 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt let newFs: vfs.FileSystem; let actualReadFileMap: Map; let host: fakes.SolutionBuilderHost; + let beforeBuildTime: number; + let afterBuildTime: number; before(() => { - assert.equal(fs.statSync(lastProjectOutputJs).mtimeMs, firstBuildTime, "First build timestamp is correct"); + beforeBuildTime = fs.statSync(lastProjectOutputJs).mtimeMs; tick(); newFs = fs.shadow(); tick(); @@ -298,14 +300,18 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt expectedBuildInfoFilesForSectionBaselines, modifyFs: incrementalModifyFs, })); - assert.equal(newFs.statSync(lastProjectOutputJs).mtimeMs, time(), "Second build timestamp is correct"); + afterBuildTime = newFs.statSync(lastProjectOutputJs).mtimeMs; }); after(() => { newFs = undefined!; actualReadFileMap = undefined!; host = undefined!; }); - if (!baselineOnly) { + it("verify build output times", () => { + assert.equal(beforeBuildTime, firstBuildTime, "First build timestamp is correct"); + assert.equal(afterBuildTime, time(), "Second build timestamp is correct"); + }); + if (!baselineOnly || verifyDiagnostics) { it(`verify diagnostics`, () => { host.assertDiagnosticMessages(...(incrementalExpectedDiagnostics || emptyArray)); }); diff --git a/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts new file mode 100644 index 0000000000000..ff9f1fc7c7afc --- /dev/null +++ b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts @@ -0,0 +1,47 @@ +namespace ts { + describe("unittests:: tsbuild:: lateBoundSymbol:: interface is merged and contains late bound member", () => { + let projFs: vfs.FileSystem; + const { time, tick } = getTime(); + before(() => { + projFs = loadProjectFromDisk("tests/projects/lateBoundSymbol", time); + }); + after(() => { + projFs = undefined!; // Release the contents + }); + + verifyTsbuildOutput({ + scenario: "interface is merged and contains late bound member", + projFs: () => projFs, + time, + tick, + proj: "lateBoundSymbol", + rootNames: ["/src/tsconfig.json"], + expectedMapFileNames: emptyArray, + lastProjectOutputJs: "/src/src/main.js", + outputFiles: [ + "/src/src/hkt.js", + "/src/src/main.js", + "/src/tsconfig.tsbuildinfo", + ], + initialBuild: { + modifyFs: noop, + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tsconfig.json", "src/src/hkt.js"], + [Diagnostics.Building_project_0, "/src/tsconfig.json"] + ] + }, + incrementalDtsUnchangedBuild: { + modifyFs: fs => replaceText(fs, "/src/src/main.ts", "const x = 10;", ""), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tsconfig.json", "src/src/hkt.js", "src/src/main.ts"], + [Diagnostics.Building_project_0, "/src/tsconfig.json"], + [Diagnostics.Updating_unchanged_output_timestamps_of_project_0, "/src/tsconfig.json"] + ] + }, + baselineOnly: true, + verifyDiagnostics: true + }); + }); +} diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js new file mode 100644 index 0000000000000..3e5da585c7cb6 --- /dev/null +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js @@ -0,0 +1,13 @@ +//// [/src/src/main.ts] +import { HKT } from "./hkt"; + +const sym = Symbol(); + +declare module "./hkt" { + interface HKT { + [sym]: { a: T } + } +} + +type A = HKT[typeof sym]; + diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js new file mode 100644 index 0000000000000..e30b62fcca876 --- /dev/null +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js @@ -0,0 +1,106 @@ +//// [/src/src/hkt.js] +"use strict"; +exports.__esModule = true; + + +//// [/src/src/main.js] +"use strict"; +exports.__esModule = true; +var sym = Symbol(); +var x = 10; + + +//// [/src/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "/lib/lib.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.es2015.d.ts": { + "version": "/lib/lib.es2015.d.ts", + "signature": "/lib/lib.es2015.d.ts" + }, + "/lib/lib.es2015.core.d.ts": { + "version": "/lib/lib.es2015.core.d.ts", + "signature": "/lib/lib.es2015.core.d.ts" + }, + "/lib/lib.es2015.collection.d.ts": { + "version": "/lib/lib.es2015.collection.d.ts", + "signature": "/lib/lib.es2015.collection.d.ts" + }, + "/lib/lib.es2015.generator.d.ts": { + "version": "/lib/lib.es2015.generator.d.ts", + "signature": "/lib/lib.es2015.generator.d.ts" + }, + "/lib/lib.es2015.iterable.d.ts": { + "version": "/lib/lib.es2015.iterable.d.ts", + "signature": "/lib/lib.es2015.iterable.d.ts" + }, + "/lib/lib.es2015.promise.d.ts": { + "version": "/lib/lib.es2015.promise.d.ts", + "signature": "/lib/lib.es2015.promise.d.ts" + }, + "/lib/lib.es2015.proxy.d.ts": { + "version": "/lib/lib.es2015.proxy.d.ts", + "signature": "/lib/lib.es2015.proxy.d.ts" + }, + "/lib/lib.es2015.reflect.d.ts": { + "version": "/lib/lib.es2015.reflect.d.ts", + "signature": "/lib/lib.es2015.reflect.d.ts" + }, + "/lib/lib.es2015.symbol.d.ts": { + "version": "/lib/lib.es2015.symbol.d.ts", + "signature": "/lib/lib.es2015.symbol.d.ts" + }, + "/lib/lib.es2015.symbol.wellknown.d.ts": { + "version": "/lib/lib.es2015.symbol.wellknown.d.ts", + "signature": "/lib/lib.es2015.symbol.wellknown.d.ts" + }, + "/src/src/hkt.ts": { + "version": "675797797", + "signature": "2373810515" + }, + "/src/src/main.ts": { + "version": "-28387946490", + "signature": "-7779857705" + } + }, + "options": { + "rootDir": "/src/src", + "lib": [ + "lib.es2015.d.ts" + ], + "incremental": true, + "configFilePath": "/src/tsconfig.json" + }, + "referencedMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "exportedModulesMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "/lib/lib.es2015.collection.d.ts", + "/lib/lib.es2015.core.d.ts", + "/lib/lib.es2015.d.ts", + "/lib/lib.es2015.generator.d.ts", + "/lib/lib.es2015.iterable.d.ts", + "/lib/lib.es2015.promise.d.ts", + "/lib/lib.es2015.proxy.d.ts", + "/lib/lib.es2015.reflect.d.ts", + "/lib/lib.es2015.symbol.d.ts", + "/lib/lib.es2015.symbol.wellknown.d.ts", + "/lib/lib.es5.d.ts", + "/src/src/hkt.ts", + "/src/src/main.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/projects/lateBoundSymbol/src/hkt.ts b/tests/projects/lateBoundSymbol/src/hkt.ts new file mode 100644 index 0000000000000..2b844a9ab7921 --- /dev/null +++ b/tests/projects/lateBoundSymbol/src/hkt.ts @@ -0,0 +1 @@ +export interface HKT { } \ No newline at end of file diff --git a/tests/projects/lateBoundSymbol/src/main.ts b/tests/projects/lateBoundSymbol/src/main.ts new file mode 100644 index 0000000000000..e5b5fcc6daa95 --- /dev/null +++ b/tests/projects/lateBoundSymbol/src/main.ts @@ -0,0 +1,11 @@ +import { HKT } from "./hkt"; + +const sym = Symbol(); + +declare module "./hkt" { + interface HKT { + [sym]: { a: T } + } +} +const x = 10; +type A = HKT[typeof sym]; \ No newline at end of file diff --git a/tests/projects/lateBoundSymbol/tsconfig.json b/tests/projects/lateBoundSymbol/tsconfig.json new file mode 100644 index 0000000000000..78bf9e23f0086 --- /dev/null +++ b/tests/projects/lateBoundSymbol/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "rootDir": "src", + "lib": [ + "es2015" + ], + "incremental": true + } +} \ No newline at end of file From 3c676087158a98efc365e0c434b80242716f40f7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 16 Apr 2019 12:36:07 -0700 Subject: [PATCH 05/16] When interfaces are merged, always ensure that the parent symbol of the late bound member symbol is declared symbol containing the node. Ensure that resolvedMembers adds the late bound symbol even when its resolved sunce lateBoundMember may or may not be added to resolved members depending on when its checked Fixes #30891 --- src/compiler/checker.ts | 15 ++- ...s-merged-and-contains-late-bound-member.js | 100 ++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0cb40d8541a55..5c2745ab3e740 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6607,12 +6607,11 @@ namespace ts { * unique symbol type which we can then use as the name of the member. This allows users * to define custom symbols that can be used in the members of an object type. * - * @param parent The containing symbol for the member. * @param earlySymbols The early-bound symbols of the parent. * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { + function lateBindMember(earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -6643,6 +6642,7 @@ namespace ts { } lateSymbol.nameType = type; addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); + const parent = getSymbolOfNode(decl.parent); if (lateSymbol.parent) { Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); } @@ -6652,6 +6652,15 @@ namespace ts { return links.resolvedSymbol = lateSymbol; } } + else { + const type = checkComputedPropertyName(decl.name); + if (isTypeUsableAsPropertyName(type)) { + const memberName = getPropertyNameFromType(type); + if (!lateSymbols.has(memberName)) { + lateSymbols.set(memberName, links.resolvedSymbol); + } + } + } return links.resolvedSymbol; } @@ -6675,7 +6684,7 @@ namespace ts { if (members) { for (const member of members) { if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { - lateBindMember(symbol, earlySymbols, lateSymbols, member); + lateBindMember(earlySymbols, lateSymbols, member); } } } diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js index 3e5da585c7cb6..89748694bbc31 100644 --- a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js @@ -1,3 +1,9 @@ +//// [/src/src/main.js] +"use strict"; +exports.__esModule = true; +var sym = Symbol(); + + //// [/src/src/main.ts] import { HKT } from "./hkt"; @@ -11,3 +17,97 @@ declare module "./hkt" { type A = HKT[typeof sym]; +//// [/src/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "/lib/lib.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.es2015.d.ts": { + "version": "/lib/lib.es2015.d.ts", + "signature": "/lib/lib.es2015.d.ts" + }, + "/lib/lib.es2015.core.d.ts": { + "version": "/lib/lib.es2015.core.d.ts", + "signature": "/lib/lib.es2015.core.d.ts" + }, + "/lib/lib.es2015.collection.d.ts": { + "version": "/lib/lib.es2015.collection.d.ts", + "signature": "/lib/lib.es2015.collection.d.ts" + }, + "/lib/lib.es2015.generator.d.ts": { + "version": "/lib/lib.es2015.generator.d.ts", + "signature": "/lib/lib.es2015.generator.d.ts" + }, + "/lib/lib.es2015.iterable.d.ts": { + "version": "/lib/lib.es2015.iterable.d.ts", + "signature": "/lib/lib.es2015.iterable.d.ts" + }, + "/lib/lib.es2015.promise.d.ts": { + "version": "/lib/lib.es2015.promise.d.ts", + "signature": "/lib/lib.es2015.promise.d.ts" + }, + "/lib/lib.es2015.proxy.d.ts": { + "version": "/lib/lib.es2015.proxy.d.ts", + "signature": "/lib/lib.es2015.proxy.d.ts" + }, + "/lib/lib.es2015.reflect.d.ts": { + "version": "/lib/lib.es2015.reflect.d.ts", + "signature": "/lib/lib.es2015.reflect.d.ts" + }, + "/lib/lib.es2015.symbol.d.ts": { + "version": "/lib/lib.es2015.symbol.d.ts", + "signature": "/lib/lib.es2015.symbol.d.ts" + }, + "/lib/lib.es2015.symbol.wellknown.d.ts": { + "version": "/lib/lib.es2015.symbol.wellknown.d.ts", + "signature": "/lib/lib.es2015.symbol.wellknown.d.ts" + }, + "/src/src/hkt.ts": { + "version": "675797797", + "signature": "2373810515" + }, + "/src/src/main.ts": { + "version": "-27494779858", + "signature": "-7779857705" + } + }, + "options": { + "rootDir": "/src/src", + "lib": [ + "lib.es2015.d.ts" + ], + "incremental": true, + "configFilePath": "/src/tsconfig.json" + }, + "referencedMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "exportedModulesMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "/lib/lib.es2015.collection.d.ts", + "/lib/lib.es2015.core.d.ts", + "/lib/lib.es2015.d.ts", + "/lib/lib.es2015.generator.d.ts", + "/lib/lib.es2015.iterable.d.ts", + "/lib/lib.es2015.promise.d.ts", + "/lib/lib.es2015.proxy.d.ts", + "/lib/lib.es2015.reflect.d.ts", + "/lib/lib.es2015.symbol.d.ts", + "/lib/lib.es2015.symbol.wellknown.d.ts", + "/lib/lib.es5.d.ts", + "/src/src/hkt.ts", + "/src/src/main.ts" + ] + }, + "version": "FakeTSVersion" +} + From 15ae8a72731adabf1f2c139a2531aa330c155e34 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 16 Apr 2019 16:18:05 -0700 Subject: [PATCH 06/16] Make sure to emit again if change in compiler option affects emit Fixes #30736 --- src/compiler/builder.ts | 5 +- src/compiler/commandLineParser.ts | 30 +++++++ src/compiler/types.ts | 1 + src/compiler/utilities.ts | 5 ++ src/testRunner/unittests/tsbuild/helpers.ts | 2 +- src/testRunner/unittests/tsbuild/sample.ts | 41 ++++++++++ .../when-declaration-option-changes.js | 77 +++++++++++++++++ .../when-declaration-option-changes.js | 82 +++++++++++++++++++ 8 files changed, 238 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js create mode 100644 tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index f72f30b226cab..ef22ec250b3d2 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -236,10 +236,7 @@ namespace ts { } }); - if (oldCompilerOptions && - (oldCompilerOptions.outDir !== compilerOptions.outDir || - oldCompilerOptions.declarationDir !== compilerOptions.declarationDir || - (oldCompilerOptions.outFile || oldCompilerOptions.out) !== (compilerOptions.outFile || compilerOptions.out))) { + if (oldCompilerOptions && compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions)) { // Add all files to affectedFilesPendingEmit since emit changed state.affectedFilesPendingEmit = concatenate(state.affectedFilesPendingEmit, newProgram.getSourceFiles().map(f => f.path)); if (state.affectedFilesPendingEmitIndex === undefined) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 12a20e0df42e1..edb25e9cb717a 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -281,6 +281,7 @@ namespace ts { name: "declaration", shortName: "d", type: "boolean", + affectsEmit: true, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, description: Diagnostics.Generates_corresponding_d_ts_file, @@ -288,6 +289,7 @@ namespace ts { { name: "declarationMap", type: "boolean", + affectsEmit: true, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, description: Diagnostics.Generates_a_sourcemap_for_each_corresponding_d_ts_file, @@ -295,12 +297,14 @@ namespace ts { { name: "emitDeclarationOnly", type: "boolean", + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Only_emit_d_ts_declaration_files, }, { name: "sourceMap", type: "boolean", + affectsEmit: true, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, description: Diagnostics.Generates_corresponding_map_file, @@ -308,6 +312,7 @@ namespace ts { { name: "outFile", type: "string", + affectsEmit: true, isFilePath: true, paramType: Diagnostics.FILE, showInSimplifiedHelpView: true, @@ -317,6 +322,7 @@ namespace ts { { name: "outDir", type: "string", + affectsEmit: true, isFilePath: true, paramType: Diagnostics.DIRECTORY, showInSimplifiedHelpView: true, @@ -326,6 +332,7 @@ namespace ts { { name: "rootDir", type: "string", + affectsEmit: true, isFilePath: true, paramType: Diagnostics.LOCATION, category: Diagnostics.Basic_Options, @@ -334,6 +341,7 @@ namespace ts { { name: "composite", type: "boolean", + affectsEmit: true, isTSConfigOnly: true, category: Diagnostics.Basic_Options, description: Diagnostics.Enable_project_compilation, @@ -341,6 +349,7 @@ namespace ts { { name: "tsBuildInfoFile", type: "string", + affectsEmit: true, isFilePath: true, paramType: Diagnostics.FILE, category: Diagnostics.Basic_Options, @@ -349,6 +358,7 @@ namespace ts { { name: "removeComments", type: "boolean", + affectsEmit: true, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, description: Diagnostics.Do_not_emit_comments_to_output, @@ -356,6 +366,7 @@ namespace ts { { name: "noEmit", type: "boolean", + affectsEmit: true, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, description: Diagnostics.Do_not_emit_outputs, @@ -363,12 +374,14 @@ namespace ts { { name: "importHelpers", type: "boolean", + affectsEmit: true, category: Diagnostics.Basic_Options, description: Diagnostics.Import_emit_helpers_from_tslib }, { name: "downlevelIteration", type: "boolean", + affectsEmit: true, category: Diagnostics.Basic_Options, description: Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3 }, @@ -580,6 +593,7 @@ namespace ts { { name: "sourceRoot", type: "string", + affectsEmit: true, paramType: Diagnostics.LOCATION, category: Diagnostics.Source_Map_Options, description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, @@ -587,6 +601,7 @@ namespace ts { { name: "mapRoot", type: "string", + affectsEmit: true, paramType: Diagnostics.LOCATION, category: Diagnostics.Source_Map_Options, description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, @@ -594,12 +609,14 @@ namespace ts { { name: "inlineSourceMap", type: "boolean", + affectsEmit: true, category: Diagnostics.Source_Map_Options, description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file }, { name: "inlineSources", type: "boolean", + affectsEmit: true, category: Diagnostics.Source_Map_Options, description: Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set }, @@ -635,6 +652,7 @@ namespace ts { { name: "out", type: "string", + affectsEmit: true, isFilePath: false, // This is intentionally broken to support compatability with existing tsconfig files // for correct behaviour, please use outFile category: Diagnostics.Advanced_Options, @@ -644,6 +662,7 @@ namespace ts { { name: "reactNamespace", type: "string", + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit }, @@ -662,6 +681,7 @@ namespace ts { { name: "emitBOM", type: "boolean", + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files }, @@ -677,6 +697,7 @@ namespace ts { crlf: NewLineKind.CarriageReturnLineFeed, lf: NewLineKind.LineFeed }), + affectsEmit: true, paramType: Diagnostics.NEWLINE, category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, @@ -704,6 +725,7 @@ namespace ts { { name: "stripInternal", type: "boolean", + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation, }, @@ -724,24 +746,28 @@ namespace ts { { name: "noEmitHelpers", type: "boolean", + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output }, { name: "noEmitOnError", type: "boolean", + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported, }, { name: "preserveConstEnums", type: "boolean", + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code }, { name: "declarationDir", type: "string", + affectsEmit: true, isFilePath: true, paramType: Diagnostics.DIRECTORY, category: Diagnostics.Advanced_Options, @@ -826,6 +852,10 @@ namespace ts { export const semanticDiagnosticsOptionDeclarations: ReadonlyArray = optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics); + /* @internal */ + export const affectsEmitOptionDeclarations: ReadonlyArray = + optionDeclarations.filter(option => !!option.affectsEmit); + /* @internal */ export const moduleResolutionOptionDeclarations: ReadonlyArray = optionDeclarations.filter(option => !!option.affectsModuleResolution); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 23d72875e4f1b..3f0d72d4ad152 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4823,6 +4823,7 @@ namespace ts { affectsModuleResolution?: true; // currently same effect as `affectsSourceFile` affectsBindDiagnostics?: true; // true if this affects binding (currently same effect as `affectsSourceFile`) affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics + affectsEmit?: true; // true if the options affects emit } /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index eca7dc7aee97b..2e6c3ae4f866e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7320,6 +7320,11 @@ namespace ts { semanticDiagnosticsOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option))); } + export function compilerOptionsAffectEmit(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { + return oldOptions !== newOptions && + affectsEmitOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option))); + } + export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown { return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : options[option.name]; } diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 6915dd5d3b75b..538ebd75cdb8a 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -305,7 +305,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt actualReadFileMap = undefined!; host = undefined!; }); - if (!baselineOnly) { + if (!baselineOnly || verifyDiagnostics) { it(`verify diagnostics`, () => { host.assertDiagnosticMessages(...(incrementalExpectedDiagnostics || emptyArray)); }); diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index 588eb256eda43..ab9210451aa99 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -720,6 +720,47 @@ class someClass { }`), "/src/tests/tsconfig.tsbuildinfo", ] }); + + verifyTsbuildOutput({ + scenario: "when declaration option changes", + projFs: () => projFs, + time, + tick, + proj: "sample1", + rootNames: ["/src/core"], + expectedMapFileNames: emptyArray, + lastProjectOutputJs: "/src/core/index.js", + initialBuild: { + modifyFs: fs => fs.writeFileSync("/src/core/tsconfig.json", `{ + "compilerOptions": { + "incremental": true, + "skipDefaultLibCheck": true + } +}`), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], + [Diagnostics.Building_project_0, "/src/core/tsconfig.json"], + ] + }, + incrementalDtsChangedBuild: { + modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", `"incremental": true,`, `"incremental": true, "declaration": true,`), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.d.ts"], + [Diagnostics.Building_project_0, "/src/core/tsconfig.json"] + ] + }, + outputFiles: [ + "/src/core/anotherModule.js", + "/src/core/anotherModule.d.ts", + "/src/core/index.js", + "/src/core/index.d.ts", + "/src/core/tsconfig.tsbuildinfo", + ], + baselineOnly: true, + verifyDiagnostics: true + }); }); }); } diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js new file mode 100644 index 0000000000000..ad16296e10cf1 --- /dev/null +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js @@ -0,0 +1,77 @@ +//// [/src/core/anotherModule.d.ts] +export declare const World = "hello"; + + +//// [/src/core/index.d.ts] +export declare const someString: string; +export declare function leftPad(s: string, n: number): string; +export declare function multiply(a: number, b: number): number; + + +//// [/src/core/tsconfig.json] +{ + "compilerOptions": { + "incremental": true, "declaration": true, + "skipDefaultLibCheck": true + } +} + +//// [/src/core/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "/lib/lib.d.ts": { + "version": "/lib/lib.d.ts", + "signature": "/lib/lib.d.ts" + }, + "/lib/lib.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.dom.d.ts": { + "version": "/lib/lib.dom.d.ts", + "signature": "/lib/lib.dom.d.ts" + }, + "/lib/lib.webworker.importscripts.d.ts": { + "version": "/lib/lib.webworker.importscripts.d.ts", + "signature": "/lib/lib.webworker.importscripts.d.ts" + }, + "/lib/lib.scripthost.d.ts": { + "version": "/lib/lib.scripthost.d.ts", + "signature": "/lib/lib.scripthost.d.ts" + }, + "/src/core/anothermodule.ts": { + "version": "-2676574883", + "signature": "-8396256275" + }, + "/src/core/index.ts": { + "version": "-18749805970", + "signature": "1874987148" + }, + "/src/core/some_decl.d.ts": { + "version": "-9253692965", + "signature": "-9253692965" + } + }, + "options": { + "incremental": true, + "declaration": true, + "skipDefaultLibCheck": true, + "configFilePath": "/src/core/tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "/lib/lib.d.ts", + "/lib/lib.dom.d.ts", + "/lib/lib.es5.d.ts", + "/lib/lib.scripthost.d.ts", + "/lib/lib.webworker.importscripts.d.ts", + "/src/core/anothermodule.ts", + "/src/core/index.ts", + "/src/core/some_decl.d.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js new file mode 100644 index 0000000000000..341b277de0dcb --- /dev/null +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js @@ -0,0 +1,82 @@ +//// [/src/core/anotherModule.js] +"use strict"; +exports.__esModule = true; +exports.World = "hello"; + + +//// [/src/core/index.js] +"use strict"; +exports.__esModule = true; +exports.someString = "HELLO WORLD"; +function leftPad(s, n) { return s + n; } +exports.leftPad = leftPad; +function multiply(a, b) { return a * b; } +exports.multiply = multiply; + + +//// [/src/core/tsconfig.json] +{ + "compilerOptions": { + "incremental": true, + "skipDefaultLibCheck": true + } +} + +//// [/src/core/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "/lib/lib.d.ts": { + "version": "/lib/lib.d.ts", + "signature": "/lib/lib.d.ts" + }, + "/lib/lib.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.dom.d.ts": { + "version": "/lib/lib.dom.d.ts", + "signature": "/lib/lib.dom.d.ts" + }, + "/lib/lib.webworker.importscripts.d.ts": { + "version": "/lib/lib.webworker.importscripts.d.ts", + "signature": "/lib/lib.webworker.importscripts.d.ts" + }, + "/lib/lib.scripthost.d.ts": { + "version": "/lib/lib.scripthost.d.ts", + "signature": "/lib/lib.scripthost.d.ts" + }, + "/src/core/anothermodule.ts": { + "version": "-2676574883", + "signature": "-8396256275" + }, + "/src/core/index.ts": { + "version": "-18749805970", + "signature": "1874987148" + }, + "/src/core/some_decl.d.ts": { + "version": "-9253692965", + "signature": "-9253692965" + } + }, + "options": { + "incremental": true, + "skipDefaultLibCheck": true, + "configFilePath": "/src/core/tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "/lib/lib.d.ts", + "/lib/lib.dom.d.ts", + "/lib/lib.es5.d.ts", + "/lib/lib.scripthost.d.ts", + "/lib/lib.webworker.importscripts.d.ts", + "/src/core/anothermodule.ts", + "/src/core/index.ts", + "/src/core/some_decl.d.ts" + ] + }, + "version": "FakeTSVersion" +} + From efa16ac11f5e06ed15097b0a81e4d7932deefab4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 16 Apr 2019 17:41:33 -0700 Subject: [PATCH 07/16] Address CR feedback --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bfca2519eb783..5e7d563bfd240 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14960,8 +14960,8 @@ namespace ts { } // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. - const indexType = source.symbol && source.symbol.flags & SymbolFlags.Enum && getEnumKind(source.symbol) === EnumKind.Literal ? - undefined : getIndexTypeOfType(source, IndexKind.String) || getIndexTypeOfType(source, IndexKind.Number); + const indexInfo = getIndexInfoOfType(source, IndexKind.String) || getIndexInfoOfType(source, IndexKind.Number); + const indexType = indexInfo && indexInfo !== enumNumberIndexInfo ? indexInfo.type : undefined; const sourcePropsType = indexType || getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)); inferFromTypes(sourcePropsType, getTemplateTypeFromMappedType(target)); return true; From 3435451dcc277b5230254af321415527aae032da Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 16 Apr 2019 18:26:24 -0700 Subject: [PATCH 08/16] Even more succinct --- src/compiler/checker.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5e7d563bfd240..e047c00d9531f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14960,9 +14960,8 @@ namespace ts { } // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. - const indexInfo = getIndexInfoOfType(source, IndexKind.String) || getIndexInfoOfType(source, IndexKind.Number); - const indexType = indexInfo && indexInfo !== enumNumberIndexInfo ? indexInfo.type : undefined; - const sourcePropsType = indexType || getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)); + const indexInfo = getIndexInfoOfType(source, IndexKind.String) || getNonEnumNumberIndexInfo(source); + const sourcePropsType = indexInfo && indexInfo.type || getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)); inferFromTypes(sourcePropsType, getTemplateTypeFromMappedType(target)); return true; } From 169e485d9096dcc32daddc1f18ccf9ee39164349 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 16 Apr 2019 21:58:48 -0700 Subject: [PATCH 09/16] Perform excess property checking on intersection and union members (#30853) * Perform excess property checking on intersection and union members * Allow partial union props to contain the undefined type * Add test case from #30771 * Un-terse getPossiblePropertiesOfUnionType side-effecting code * Fix bug exposed in RWC * Cache results of getPossiblePropertiesOfUnionType * Fix whitespace --- src/compiler/checker.ts | 96 +++++---- src/compiler/types.ts | 28 +-- ...heckingWhenTargetIsIntersection.errors.txt | 48 +++++ ...ropertyCheckingWhenTargetIsIntersection.js | 39 ++++ ...tyCheckingWhenTargetIsIntersection.symbols | 71 +++++++ ...ertyCheckingWhenTargetIsIntersection.types | 70 ++++++ .../excessPropertyCheckWithUnions.errors.txt | 16 +- ...tyChecksWithNestedIntersections.errors.txt | 116 ++++++++++ ...ssPropertyChecksWithNestedIntersections.js | 100 +++++++++ ...pertyChecksWithNestedIntersections.symbols | 190 +++++++++++++++++ ...ropertyChecksWithNestedIntersections.types | 201 ++++++++++++++++++ ...tUnionNestedExcessPropertyCheck.errors.txt | 44 ++++ ...nonObjectUnionNestedExcessPropertyCheck.js | 29 +++ ...jectUnionNestedExcessPropertyCheck.symbols | 46 ++++ ...ObjectUnionNestedExcessPropertyCheck.types | 49 +++++ ...tyCheckNoApparentPropTypeMismatchErrors.js | 17 ++ ...ckNoApparentPropTypeMismatchErrors.symbols | 41 ++++ ...heckNoApparentPropTypeMismatchErrors.types | 33 +++ .../unionExcessPropsWithPartialMember.js | 31 +++ .../unionExcessPropsWithPartialMember.symbols | 35 +++ .../unionExcessPropsWithPartialMember.types | 34 +++ ...ropertyCheckingWhenTargetIsIntersection.ts | 27 +++ ...ssPropertyChecksWithNestedIntersections.ts | 70 ++++++ ...nonObjectUnionNestedExcessPropertyCheck.ts | 19 ++ ...tyCheckNoApparentPropTypeMismatchErrors.ts | 11 + .../unionExcessPropsWithPartialMember.ts | 15 ++ 26 files changed, 1414 insertions(+), 62 deletions(-) create mode 100644 tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt create mode 100644 tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.js create mode 100644 tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.symbols create mode 100644 tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.types create mode 100644 tests/baselines/reference/excessPropertyChecksWithNestedIntersections.errors.txt create mode 100644 tests/baselines/reference/excessPropertyChecksWithNestedIntersections.js create mode 100644 tests/baselines/reference/excessPropertyChecksWithNestedIntersections.symbols create mode 100644 tests/baselines/reference/excessPropertyChecksWithNestedIntersections.types create mode 100644 tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.errors.txt create mode 100644 tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.js create mode 100644 tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.symbols create mode 100644 tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.types create mode 100644 tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.js create mode 100644 tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.symbols create mode 100644 tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.types create mode 100644 tests/baselines/reference/unionExcessPropsWithPartialMember.js create mode 100644 tests/baselines/reference/unionExcessPropsWithPartialMember.symbols create mode 100644 tests/baselines/reference/unionExcessPropsWithPartialMember.types create mode 100644 tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts create mode 100644 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts create mode 100644 tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts create mode 100644 tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts create mode 100644 tests/cases/compiler/unionExcessPropsWithPartialMember.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0cb40d8541a55..0c91e1ba06208 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7473,6 +7473,25 @@ namespace ts { return type.resolvedProperties; } + function getPossiblePropertiesOfUnionType(type: UnionType): Symbol[] { + if (type.possiblePropertyCache) { + return type.possiblePropertyCache.size ? arrayFrom(type.possiblePropertyCache.values()) : emptyArray; + } + type.possiblePropertyCache = createSymbolTable(); + for (const t of type.types) { + for (const p of getPropertiesOfType(t)) { + if (!type.possiblePropertyCache.has(p.escapedName)) { + const prop = getUnionOrIntersectionProperty(type, p.escapedName); + if (prop) { + type.possiblePropertyCache.set(p.escapedName, prop); + } + } + } + } + // We can't simply use the normal property cache here, since that will contain cached apparent type members :( + return type.possiblePropertyCache.size ? arrayFrom(type.possiblePropertyCache.values()) : emptyArray; + } + function getPropertiesOfType(type: Type): Symbol[] { type = getApparentType(type); return type.flags & TypeFlags.UnionOrIntersection ? @@ -7830,7 +7849,7 @@ namespace ts { const isUnion = containingType.flags & TypeFlags.Union; const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0; // Flags we want to propagate to the result if they exist in all source symbols - let commonFlags = isUnion ? SymbolFlags.None : SymbolFlags.Optional; + let optionalFlag = isUnion ? SymbolFlags.None : SymbolFlags.Optional; let syntheticFlag = CheckFlags.SyntheticMethod; let checkFlags = 0; for (const current of containingType.types) { @@ -7839,7 +7858,12 @@ namespace ts { const prop = getPropertyOfType(type, name); const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0; if (prop && !(modifiers & excludeModifiers)) { - commonFlags &= prop.flags; + if (isUnion) { + optionalFlag |= (prop.flags & SymbolFlags.Optional); + } + else { + optionalFlag &= prop.flags; + } const id = "" + getSymbolId(prop); if (!propSet.has(id)) { propSet.set(id, prop); @@ -7857,10 +7881,11 @@ namespace ts { const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number) || getIndexInfoOfType(type, IndexKind.String)); if (indexInfo) { checkFlags |= indexInfo.isReadonly ? CheckFlags.Readonly : 0; + checkFlags |= CheckFlags.WritePartial; indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); } else { - checkFlags |= CheckFlags.Partial; + checkFlags |= CheckFlags.ReadPartial; } } } @@ -7869,7 +7894,7 @@ namespace ts { return undefined; } const props = arrayFrom(propSet.values()); - if (props.length === 1 && !(checkFlags & CheckFlags.Partial) && !indexTypes) { + if (props.length === 1 && !(checkFlags & CheckFlags.ReadPartial) && !indexTypes) { return props[0]; } let declarations: Declaration[] | undefined; @@ -7900,7 +7925,7 @@ namespace ts { propTypes.push(type); } addRange(propTypes, indexTypes); - const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags); + const result = createSymbol(SymbolFlags.Property | optionalFlag, name, syntheticFlag | checkFlags); result.containingType = containingType; if (!hasNonUniformValueDeclaration && firstValueDeclaration) { result.valueDeclaration = firstValueDeclaration; @@ -7937,7 +7962,7 @@ namespace ts { function getPropertyOfUnionOrIntersectionType(type: UnionOrIntersectionType, name: __String): Symbol | undefined { const property = getUnionOrIntersectionProperty(type, name); // We need to filter out partial properties in union types - return property && !(getCheckFlags(property) & CheckFlags.Partial) ? property : undefined; + return property && !(getCheckFlags(property) & CheckFlags.ReadPartial) ? property : undefined; } /** @@ -12276,25 +12301,6 @@ namespace ts { return true; } - function isUnionOrIntersectionTypeWithoutNullableConstituents(type: Type): boolean { - if (!(type.flags & TypeFlags.UnionOrIntersection)) { - return false; - } - // at this point we know that this is union or intersection type possibly with nullable constituents. - // check if we still will have compound type if we ignore nullable components. - let seenNonNullable = false; - for (const t of (type).types) { - if (t.flags & TypeFlags.Nullable) { - continue; - } - if (seenNonNullable) { - return true; - } - seenNonNullable = true; - } - return false; - } - /** * Compare two types and return * * Ternary.True if they are related with no assumptions, @@ -12349,7 +12355,8 @@ namespace ts { isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True; const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); - if (isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral) { + const isPerformingExcessPropertyChecks = (isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral); + if (isPerformingExcessPropertyChecks) { const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined; if (hasExcessProperties(source, target, discriminantType, reportErrors)) { if (reportErrors) { @@ -12357,13 +12364,6 @@ namespace ts { } return Ternary.False; } - // Above we check for excess properties with respect to the entire target type. When union - // and intersection types are further deconstructed on the target side, we don't want to - // make the check again (as it might fail for a partial target type). Therefore we obtain - // the regular source type and proceed with that. - if (isUnionOrIntersectionTypeWithoutNullableConstituents(target) && !discriminantType) { - source = getRegularTypeOfObjectLiteral(source); - } } if (relation !== comparableRelation && !isApparentIntersectionConstituent && @@ -12399,11 +12399,24 @@ namespace ts { } else { if (target.flags & TypeFlags.Union) { - result = typeRelatedToSomeType(source, target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive)); + result = typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive)); + if (result && isPerformingExcessPropertyChecks) { + // Validate against excess props using the original `source` + const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined; + if (!propertiesRelatedTo(source, discriminantType || target, reportErrors)) { + return Ternary.False; + } + } } else if (target.flags & TypeFlags.Intersection) { isIntersectionConstituent = true; // set here to affect the following trio of checks - result = typeRelatedToEachType(source, target as IntersectionType, reportErrors); + result = typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors); + if (result && isPerformingExcessPropertyChecks) { + // Validate against excess props using the original `source` + if (!propertiesRelatedTo(source, target, reportErrors)) { + return Ternary.False; + } + } } else if (source.flags & TypeFlags.Intersection) { // Check to see if any constituents of the intersection are immediately related to the target. @@ -12506,7 +12519,7 @@ namespace ts { // check excess properties against discriminant type only, not the entire union return hasExcessProperties(source, discriminant, /*discriminant*/ undefined, reportErrors); } - for (const prop of getPropertiesOfObjectType(source)) { + for (const prop of getPropertiesOfType(source)) { if (shouldCheckAsExcessProperty(prop, source.symbol) && !isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { if (reportErrors) { // Report error in terms of object types in the target as those are the only ones @@ -13233,7 +13246,9 @@ namespace ts { } } } - const properties = getPropertiesOfObjectType(target); + // We only call this for union target types when we're attempting to do excess property checking - in those cases, we want to get _all possible props_ + // from the target union, across all members + const properties = target.flags & TypeFlags.Union ? getPossiblePropertiesOfUnionType(target as UnionType) : getPropertiesOfType(target); for (const targetProp of properties) { if (!(targetProp.flags & SymbolFlags.Prototype)) { const sourceProp = getPropertyOfType(source, targetProp.escapedName); @@ -13281,7 +13296,8 @@ namespace ts { } return Ternary.False; } - const related = isRelatedTo(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors); + // If the target comes from a partial union prop, allow `undefined` in the target type + const related = isRelatedTo(getTypeOfSymbol(sourceProp), addOptionality(getTypeOfSymbol(targetProp), !!(getCheckFlags(targetProp) & CheckFlags.Partial)), reportErrors); if (!related) { if (reportErrors) { reportError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp)); @@ -14627,9 +14643,9 @@ namespace ts { } function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean) { - const properties = target.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(target) : getPropertiesOfObjectType(target); + const properties = target.flags & TypeFlags.Union ? getPossiblePropertiesOfUnionType(target as UnionType) : getPropertiesOfType(target); for (const targetProp of properties) { - if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) { + if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional || getCheckFlags(targetProp) & CheckFlags.Partial)) { const sourceProp = getPropertyOfType(source, targetProp.escapedName); if (!sourceProp) { yield targetProp; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 23d72875e4f1b..6fba5f149cf53 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3746,19 +3746,21 @@ namespace ts { SyntheticProperty = 1 << 1, // Property in union or intersection type SyntheticMethod = 1 << 2, // Method in union or intersection type Readonly = 1 << 3, // Readonly transient symbol - Partial = 1 << 4, // Synthetic property present in some but not all constituents - HasNonUniformType = 1 << 5, // Synthetic property with non-uniform type in constituents - HasLiteralType = 1 << 6, // Synthetic property with at least one literal type in constituents - ContainsPublic = 1 << 7, // Synthetic property with public constituent(s) - ContainsProtected = 1 << 8, // Synthetic property with protected constituent(s) - ContainsPrivate = 1 << 9, // Synthetic property with private constituent(s) - ContainsStatic = 1 << 10, // Synthetic property with static constituent(s) - Late = 1 << 11, // Late-bound symbol for a computed property with a dynamic name - ReverseMapped = 1 << 12, // Property of reverse-inferred homomorphic mapped type - OptionalParameter = 1 << 13, // Optional parameter - RestParameter = 1 << 14, // Rest parameter + ReadPartial = 1 << 4, // Synthetic property present in some but not all constituents + WritePartial = 1 << 5, // Synthetic property present in some but only satisfied by an index signature in others + HasNonUniformType = 1 << 6, // Synthetic property with non-uniform type in constituents + HasLiteralType = 1 << 7, // Synthetic property with at least one literal type in constituents + ContainsPublic = 1 << 8, // Synthetic property with public constituent(s) + ContainsProtected = 1 << 9, // Synthetic property with protected constituent(s) + ContainsPrivate = 1 << 10, // Synthetic property with private constituent(s) + ContainsStatic = 1 << 11, // Synthetic property with static constituent(s) + Late = 1 << 12, // Late-bound symbol for a computed property with a dynamic name + ReverseMapped = 1 << 13, // Property of reverse-inferred homomorphic mapped type + OptionalParameter = 1 << 14, // Optional parameter + RestParameter = 1 << 15, // Rest parameter Synthetic = SyntheticProperty | SyntheticMethod, - Discriminant = HasNonUniformType | HasLiteralType + Discriminant = HasNonUniformType | HasLiteralType, + Partial = ReadPartial | WritePartial } /* @internal */ @@ -4171,6 +4173,8 @@ namespace ts { } export interface UnionType extends UnionOrIntersectionType { + /* @internal */ + possiblePropertyCache?: SymbolTable; // Cache of _all_ resolved properties less any from aparent members } export interface IntersectionType extends UnionOrIntersectionType { diff --git a/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt new file mode 100644 index 0000000000000..6a83638ba9076 --- /dev/null +++ b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt @@ -0,0 +1,48 @@ +tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(21,33): error TS2322: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. + Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. +tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(27,34): error TS2326: Types of property 'icon' are incompatible. + Type '{ props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }' is not assignable to type 'NestedProp'. + Types of property 'props' are incompatible. + Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. + Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. + + +==== tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts (2 errors) ==== + interface StatelessComponent

{ + (props: P & { children?: number }, context?: any): null; + } + + const TestComponent: StatelessComponent = (props) => { + return null; + } + + interface ITestProps { + ariaLabel?: string; + } + + interface NestedProp { + props: TProps; + } + + interface TestProps { + icon: NestedProp; + } + + TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. +!!! error TS2322: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. +!!! related TS6500 tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts:14:3: The expected type comes from property 'props' which is declared here on type 'NestedProp' + + const TestComponent2: StatelessComponent = (props) => { + return null; + } + + TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2326: Types of property 'icon' are incompatible. +!!! error TS2326: Type '{ props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }' is not assignable to type 'NestedProp'. +!!! error TS2326: Types of property 'props' are incompatible. +!!! error TS2326: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. +!!! error TS2326: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. + \ No newline at end of file diff --git a/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.js b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.js new file mode 100644 index 0000000000000..cb0e6503b79ec --- /dev/null +++ b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.js @@ -0,0 +1,39 @@ +//// [deepExcessPropertyCheckingWhenTargetIsIntersection.ts] +interface StatelessComponent

{ + (props: P & { children?: number }, context?: any): null; +} + +const TestComponent: StatelessComponent = (props) => { + return null; +} + +interface ITestProps { + ariaLabel?: string; +} + +interface NestedProp { + props: TProps; +} + +interface TestProps { + icon: NestedProp; +} + +TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); + +const TestComponent2: StatelessComponent = (props) => { + return null; +} + +TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); + + +//// [deepExcessPropertyCheckingWhenTargetIsIntersection.js] +var TestComponent = function (props) { + return null; +}; +TestComponent({ icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } }); +var TestComponent2 = function (props) { + return null; +}; +TestComponent2({ icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } }); diff --git a/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.symbols b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.symbols new file mode 100644 index 0000000000000..717cb872cecd8 --- /dev/null +++ b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.symbols @@ -0,0 +1,71 @@ +=== tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts === +interface StatelessComponent

{ +>StatelessComponent : Symbol(StatelessComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 0)) +>P : Symbol(P, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 29)) + + (props: P & { children?: number }, context?: any): null; +>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 1, 3)) +>P : Symbol(P, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 29)) +>children : Symbol(children, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 1, 15)) +>context : Symbol(context, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 1, 36)) +} + +const TestComponent: StatelessComponent = (props) => { +>TestComponent : Symbol(TestComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 4, 5)) +>StatelessComponent : Symbol(StatelessComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 0)) +>TestProps : Symbol(TestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 14, 1)) +>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 4, 54)) + + return null; +} + +interface ITestProps { +>ITestProps : Symbol(ITestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 6, 1)) + + ariaLabel?: string; +>ariaLabel : Symbol(ITestProps.ariaLabel, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 8, 22)) +} + +interface NestedProp { +>NestedProp : Symbol(NestedProp, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 10, 1)) +>TProps : Symbol(TProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 12, 21)) + + props: TProps; +>props : Symbol(NestedProp.props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 12, 30)) +>TProps : Symbol(TProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 12, 21)) +} + +interface TestProps { +>TestProps : Symbol(TestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 14, 1)) + + icon: NestedProp; +>icon : Symbol(TestProps.icon, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 16, 21)) +>NestedProp : Symbol(NestedProp, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 10, 1)) +>ITestProps : Symbol(ITestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 6, 1)) +} + +TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); +>TestComponent : Symbol(TestComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 4, 5)) +>icon : Symbol(icon, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 15)) +>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 22)) +>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 31)) +>ariaLabel : Symbol(ariaLabel, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 59)) + +const TestComponent2: StatelessComponent = (props) => { +>TestComponent2 : Symbol(TestComponent2, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 5)) +>StatelessComponent : Symbol(StatelessComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 0)) +>TestProps : Symbol(TestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 14, 1)) +>props2 : Symbol(props2, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 54)) +>x : Symbol(x, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 63)) +>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 79)) + + return null; +} + +TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); +>TestComponent2 : Symbol(TestComponent2, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 5)) +>icon : Symbol(icon, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 16)) +>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 23)) +>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 32)) +>ariaLabel : Symbol(ariaLabel, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 60)) + diff --git a/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.types b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.types new file mode 100644 index 0000000000000..dc84ff20e08de --- /dev/null +++ b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.types @@ -0,0 +1,70 @@ +=== tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts === +interface StatelessComponent

{ + (props: P & { children?: number }, context?: any): null; +>props : P & { children?: number; } +>children : number +>context : any +>null : null +} + +const TestComponent: StatelessComponent = (props) => { +>TestComponent : StatelessComponent +>(props) => { return null;} : (props: TestProps & { children?: number; }) => any +>props : TestProps & { children?: number; } + + return null; +>null : null +} + +interface ITestProps { + ariaLabel?: string; +>ariaLabel : string +} + +interface NestedProp { + props: TProps; +>props : TProps +} + +interface TestProps { + icon: NestedProp; +>icon : NestedProp +} + +TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); +>TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}) : null +>TestComponent : StatelessComponent +>{icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }} : { icon: { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }; } +>icon : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; } +>{ props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; } +>props : { INVALID_PROP_NAME: string; ariaLabel: string; } +>{ INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } : { INVALID_PROP_NAME: string; ariaLabel: string; } +>INVALID_PROP_NAME : string +>'share' : "share" +>ariaLabel : string +>'test label' : "test label" + +const TestComponent2: StatelessComponent = (props) => { +>TestComponent2 : StatelessComponent +>props2 : { x: number; } +>x : number +>(props) => { return null;} : (props: (TestProps & { children?: number; }) | ({ props2: { x: number; }; } & { children?: number; })) => any +>props : (TestProps & { children?: number; }) | ({ props2: { x: number; }; } & { children?: number; }) + + return null; +>null : null +} + +TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); +>TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}) : null +>TestComponent2 : StatelessComponent +>{icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }} : { icon: { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }; } +>icon : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; } +>{ props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; } +>props : { INVALID_PROP_NAME: string; ariaLabel: string; } +>{ INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } : { INVALID_PROP_NAME: string; ariaLabel: string; } +>INVALID_PROP_NAME : string +>'share' : "share" +>ariaLabel : string +>'test label' : "test label" + diff --git a/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt b/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt index 5331add9e8d7a..469b6d089b696 100644 --- a/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt +++ b/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt @@ -20,11 +20,9 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(49,35): error TS2322: Type Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'. tests/cases/compiler/excessPropertyCheckWithUnions.ts(50,35): error TS2322: Type '{ a: 1; b: 1; first: string; third: string; }' is not assignable to type 'Overlapping'. Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'. -tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'. - Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type '{ kind: "A"; n: AN; }'. - Types of property 'n' are incompatible. - Type '{ a: string; b: string; }' is not assignable to type 'AN'. - Object literal may only specify known properties, and 'b' does not exist in type 'AN'. +tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2326: Types of property 'n' are incompatible. + Type '{ a: string; b: string; }' is not assignable to type 'AN'. + Object literal may only specify known properties, and 'b' does not exist in type 'AN'. ==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (10 errors) ==== @@ -127,11 +125,9 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2322: Type a: "a", b: "b", // excess -- kind: "A" ~~~~~~ -!!! error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'. -!!! error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type '{ kind: "A"; n: AN; }'. -!!! error TS2322: Types of property 'n' are incompatible. -!!! error TS2322: Type '{ a: string; b: string; }' is not assignable to type 'AN'. -!!! error TS2322: Object literal may only specify known properties, and 'b' does not exist in type 'AN'. +!!! error TS2326: Types of property 'n' are incompatible. +!!! error TS2326: Type '{ a: string; b: string; }' is not assignable to type 'AN'. +!!! error TS2326: Object literal may only specify known properties, and 'b' does not exist in type 'AN'. } } const abac: AB = { diff --git a/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.errors.txt b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.errors.txt new file mode 100644 index 0000000000000..368a71de003fc --- /dev/null +++ b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.errors.txt @@ -0,0 +1,116 @@ +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(18,19): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(19,31): error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'. + Object literal may only specify known properties, and 'y' does not exist in type 'A'. +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(22,19): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(23,31): error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'. + Object literal may only specify known properties, and 'y' does not exist in type 'A'. +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(34,5): error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'. + Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'. +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(43,9): error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'. + Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'. +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(68,32): error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'View'. + Object literal may only specify known properties, and 'boo' does not exist in type 'View'. +tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(70,50): error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'boolean | View'. + Object literal may only specify known properties, and 'boo' does not exist in type 'View'. + + +==== tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts (8 errors) ==== + // https://github.com/Microsoft/TypeScript/issues/13813 + + interface A { + x: string + } + + interface B { + a: A; + } + + interface C { + c: number; + } + + type D = B & C; + + let a: B = { a: { x: 'hello' } }; // ok + let b: B = { a: { x: 2 } }; // error - types of property x are incompatible + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:4:5: The expected type comes from property 'x' which is declared here on type 'A' + let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A + ~~~~ +!!! error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'. +!!! error TS2322: Object literal may only specify known properties, and 'y' does not exist in type 'A'. +!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:8:5: The expected type comes from property 'a' which is declared here on type 'B' + + let d: D = { a: { x: 'hello' }, c: 5 }; // ok + let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:4:5: The expected type comes from property 'x' which is declared here on type 'A' + let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error + ~~~~ +!!! error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'. +!!! error TS2322: Object literal may only specify known properties, and 'y' does not exist in type 'A'. +!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:8:5: The expected type comes from property 'a' which is declared here on type 'D' + + // https://github.com/Microsoft/TypeScript/issues/18075 + + export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } } + + export let obj: MyType; + + export const photo: typeof obj.photo = { + id: 1, + url: '', + xyz: 1 // Great! This causes an error! + ~~~~~~ +!!! error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'. +!!! error TS2322: Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'. + }; + + export const myInstance: MyType = { + id: 1, + name: '', + photo: { + id: 1, + url: '', + xyz: 2 // This should also be an error + ~~~~~~ +!!! error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'. +!!! error TS2322: Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'. +!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:27:62: The expected type comes from property 'photo' which is declared here on type 'MyType' + } + }; + + // https://github.com/Microsoft/TypeScript/issues/28616 + + export type View = { [K in keyof T]: T[K] extends object ? boolean | View : boolean }; + + interface TypeC { + foo: string; + bar: string; + } + + interface TypeB { + foo: string, + bar: TypeC + } + + interface TypeA { + foo: string, + bar: TypeB, + } + + let test: View; + + test = { foo: true, bar: true, boo: true } + ~~~~~~~~~ +!!! error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'View'. +!!! error TS2322: Object literal may only specify known properties, and 'boo' does not exist in type 'View'. + + test = { foo: true, bar: { foo: true, bar: true, boo: true } } + ~~~~~~~~~ +!!! error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'boolean | View'. +!!! error TS2322: Object literal may only specify known properties, and 'boo' does not exist in type 'View'. +!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:63:5: The expected type comes from property 'bar' which is declared here on type 'View' + \ No newline at end of file diff --git a/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.js b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.js new file mode 100644 index 0000000000000..f43b7bf83a47a --- /dev/null +++ b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.js @@ -0,0 +1,100 @@ +//// [excessPropertyChecksWithNestedIntersections.ts] +// https://github.com/Microsoft/TypeScript/issues/13813 + +interface A { + x: string +} + +interface B { + a: A; +} + +interface C { + c: number; +} + +type D = B & C; + +let a: B = { a: { x: 'hello' } }; // ok +let b: B = { a: { x: 2 } }; // error - types of property x are incompatible +let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A + +let d: D = { a: { x: 'hello' }, c: 5 }; // ok +let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible +let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error + +// https://github.com/Microsoft/TypeScript/issues/18075 + +export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } } + +export let obj: MyType; + +export const photo: typeof obj.photo = { + id: 1, + url: '', + xyz: 1 // Great! This causes an error! +}; + +export const myInstance: MyType = { + id: 1, + name: '', + photo: { + id: 1, + url: '', + xyz: 2 // This should also be an error + } +}; + +// https://github.com/Microsoft/TypeScript/issues/28616 + +export type View = { [K in keyof T]: T[K] extends object ? boolean | View : boolean }; + +interface TypeC { + foo: string; + bar: string; +} + +interface TypeB { + foo: string, + bar: TypeC +} + +interface TypeA { + foo: string, + bar: TypeB, +} + +let test: View; + +test = { foo: true, bar: true, boo: true } + +test = { foo: true, bar: { foo: true, bar: true, boo: true } } + + +//// [excessPropertyChecksWithNestedIntersections.js] +"use strict"; +// https://github.com/Microsoft/TypeScript/issues/13813 +exports.__esModule = true; +var a = { a: { x: 'hello' } }; // ok +var b = { a: { x: 2 } }; // error - types of property x are incompatible +var c = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A +var d = { a: { x: 'hello' }, c: 5 }; // ok +var e = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible +var f = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error +exports.photo = { + id: 1, + url: '', + xyz: 1 // Great! This causes an error! +}; +exports.myInstance = { + id: 1, + name: '', + photo: { + id: 1, + url: '', + xyz: 2 // This should also be an error + } +}; +var test; +test = { foo: true, bar: true, boo: true }; +test = { foo: true, bar: { foo: true, bar: true, boo: true } }; diff --git a/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.symbols b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.symbols new file mode 100644 index 0000000000000..bf10195045e35 --- /dev/null +++ b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.symbols @@ -0,0 +1,190 @@ +=== tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts === +// https://github.com/Microsoft/TypeScript/issues/13813 + +interface A { +>A : Symbol(A, Decl(excessPropertyChecksWithNestedIntersections.ts, 0, 0)) + + x: string +>x : Symbol(A.x, Decl(excessPropertyChecksWithNestedIntersections.ts, 2, 13)) +} + +interface B { +>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1)) + + a: A; +>a : Symbol(B.a, Decl(excessPropertyChecksWithNestedIntersections.ts, 6, 13)) +>A : Symbol(A, Decl(excessPropertyChecksWithNestedIntersections.ts, 0, 0)) +} + +interface C { +>C : Symbol(C, Decl(excessPropertyChecksWithNestedIntersections.ts, 8, 1)) + + c: number; +>c : Symbol(C.c, Decl(excessPropertyChecksWithNestedIntersections.ts, 10, 13)) +} + +type D = B & C; +>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1)) +>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1)) +>C : Symbol(C, Decl(excessPropertyChecksWithNestedIntersections.ts, 8, 1)) + +let a: B = { a: { x: 'hello' } }; // ok +>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 16, 3)) +>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1)) +>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 16, 12)) +>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 16, 17)) + +let b: B = { a: { x: 2 } }; // error - types of property x are incompatible +>b : Symbol(b, Decl(excessPropertyChecksWithNestedIntersections.ts, 17, 3)) +>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1)) +>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 17, 12)) +>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 17, 17)) + +let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A +>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 3)) +>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1)) +>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 12)) +>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 17)) +>y : Symbol(y, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 29)) + +let d: D = { a: { x: 'hello' }, c: 5 }; // ok +>d : Symbol(d, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 3)) +>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1)) +>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 12)) +>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 17)) +>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 31)) + +let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible +>e : Symbol(e, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 3)) +>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1)) +>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 12)) +>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 17)) +>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 25)) + +let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error +>f : Symbol(f, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 3)) +>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1)) +>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 12)) +>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 17)) +>y : Symbol(y, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 29)) +>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 37)) + +// https://github.com/Microsoft/TypeScript/issues/18075 + +export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } } +>MyType : Symbol(MyType, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 45)) +>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 22)) +>name : Symbol(name, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 40)) +>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 60)) +>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 69)) +>url : Symbol(url, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 87)) + +export let obj: MyType; +>obj : Symbol(obj, Decl(excessPropertyChecksWithNestedIntersections.ts, 28, 10)) +>MyType : Symbol(MyType, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 45)) + +export const photo: typeof obj.photo = { +>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 30, 12)) +>obj.photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 60)) +>obj : Symbol(obj, Decl(excessPropertyChecksWithNestedIntersections.ts, 28, 10)) +>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 60)) + + id: 1, +>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 30, 40)) + + url: '', +>url : Symbol(url, Decl(excessPropertyChecksWithNestedIntersections.ts, 31, 10)) + + xyz: 1 // Great! This causes an error! +>xyz : Symbol(xyz, Decl(excessPropertyChecksWithNestedIntersections.ts, 32, 12)) + +}; + +export const myInstance: MyType = { +>myInstance : Symbol(myInstance, Decl(excessPropertyChecksWithNestedIntersections.ts, 36, 12)) +>MyType : Symbol(MyType, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 45)) + + id: 1, +>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 36, 35)) + + name: '', +>name : Symbol(name, Decl(excessPropertyChecksWithNestedIntersections.ts, 37, 10)) + + photo: { +>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 38, 13)) + + id: 1, +>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 39, 12)) + + url: '', +>url : Symbol(url, Decl(excessPropertyChecksWithNestedIntersections.ts, 40, 14)) + + xyz: 2 // This should also be an error +>xyz : Symbol(xyz, Decl(excessPropertyChecksWithNestedIntersections.ts, 41, 16)) + } +}; + +// https://github.com/Microsoft/TypeScript/issues/28616 + +export type View = { [K in keyof T]: T[K] extends object ? boolean | View : boolean }; +>View : Symbol(View, Decl(excessPropertyChecksWithNestedIntersections.ts, 44, 2)) +>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17)) +>K : Symbol(K, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 25)) +>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17)) +>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17)) +>K : Symbol(K, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 25)) +>View : Symbol(View, Decl(excessPropertyChecksWithNestedIntersections.ts, 44, 2)) +>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17)) +>K : Symbol(K, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 25)) + +interface TypeC { +>TypeC : Symbol(TypeC, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 95)) + + foo: string; +>foo : Symbol(TypeC.foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 50, 17)) + + bar: string; +>bar : Symbol(TypeC.bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 51, 16)) +} + +interface TypeB { +>TypeB : Symbol(TypeB, Decl(excessPropertyChecksWithNestedIntersections.ts, 53, 1)) + + foo: string, +>foo : Symbol(TypeB.foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 55, 17)) + + bar: TypeC +>bar : Symbol(TypeB.bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 56, 16)) +>TypeC : Symbol(TypeC, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 95)) +} + +interface TypeA { +>TypeA : Symbol(TypeA, Decl(excessPropertyChecksWithNestedIntersections.ts, 58, 1)) + + foo: string, +>foo : Symbol(TypeA.foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 60, 17)) + + bar: TypeB, +>bar : Symbol(TypeA.bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 61, 16)) +>TypeB : Symbol(TypeB, Decl(excessPropertyChecksWithNestedIntersections.ts, 53, 1)) +} + +let test: View; +>test : Symbol(test, Decl(excessPropertyChecksWithNestedIntersections.ts, 65, 3)) +>View : Symbol(View, Decl(excessPropertyChecksWithNestedIntersections.ts, 44, 2)) +>TypeA : Symbol(TypeA, Decl(excessPropertyChecksWithNestedIntersections.ts, 58, 1)) + +test = { foo: true, bar: true, boo: true } +>test : Symbol(test, Decl(excessPropertyChecksWithNestedIntersections.ts, 65, 3)) +>foo : Symbol(foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 67, 8)) +>bar : Symbol(bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 67, 19)) +>boo : Symbol(boo, Decl(excessPropertyChecksWithNestedIntersections.ts, 67, 30)) + +test = { foo: true, bar: { foo: true, bar: true, boo: true } } +>test : Symbol(test, Decl(excessPropertyChecksWithNestedIntersections.ts, 65, 3)) +>foo : Symbol(foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 8)) +>bar : Symbol(bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 19)) +>foo : Symbol(foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 26)) +>bar : Symbol(bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 37)) +>boo : Symbol(boo, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 48)) + diff --git a/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.types b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.types new file mode 100644 index 0000000000000..d15b8f7e0dded --- /dev/null +++ b/tests/baselines/reference/excessPropertyChecksWithNestedIntersections.types @@ -0,0 +1,201 @@ +=== tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts === +// https://github.com/Microsoft/TypeScript/issues/13813 + +interface A { + x: string +>x : string +} + +interface B { + a: A; +>a : A +} + +interface C { + c: number; +>c : number +} + +type D = B & C; +>D : D + +let a: B = { a: { x: 'hello' } }; // ok +>a : B +>{ a: { x: 'hello' } } : { a: { x: string; }; } +>a : { x: string; } +>{ x: 'hello' } : { x: string; } +>x : string +>'hello' : "hello" + +let b: B = { a: { x: 2 } }; // error - types of property x are incompatible +>b : B +>{ a: { x: 2 } } : { a: { x: number; }; } +>a : { x: number; } +>{ x: 2 } : { x: number; } +>x : number +>2 : 2 + +let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A +>c : B +>{ a: { x: 'hello', y: 2 } } : { a: { x: string; y: number; }; } +>a : { x: string; y: number; } +>{ x: 'hello', y: 2 } : { x: string; y: number; } +>x : string +>'hello' : "hello" +>y : number +>2 : 2 + +let d: D = { a: { x: 'hello' }, c: 5 }; // ok +>d : D +>{ a: { x: 'hello' }, c: 5 } : { a: { x: string; }; c: number; } +>a : { x: string; } +>{ x: 'hello' } : { x: string; } +>x : string +>'hello' : "hello" +>c : number +>5 : 5 + +let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible +>e : D +>{ a: { x: 2 }, c: 5 } : { a: { x: number; }; c: number; } +>a : { x: number; } +>{ x: 2 } : { x: number; } +>x : number +>2 : 2 +>c : number +>5 : 5 + +let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error +>f : D +>{ a: { x: 'hello', y: 2 }, c: 5 } : { a: { x: string; y: number; }; c: number; } +>a : { x: string; y: number; } +>{ x: 'hello', y: 2 } : { x: string; y: number; } +>x : string +>'hello' : "hello" +>y : number +>2 : 2 +>c : number +>5 : 5 + +// https://github.com/Microsoft/TypeScript/issues/18075 + +export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } } +>MyType : MyType +>id : number +>name : string +>photo : { id: number; } & { url: string; } +>id : number +>url : string + +export let obj: MyType; +>obj : MyType + +export const photo: typeof obj.photo = { +>photo : { id: number; } & { url: string; } +>obj.photo : { id: number; } & { url: string; } +>obj : MyType +>photo : { id: number; } & { url: string; } +>{ id: 1, url: '', xyz: 1 // Great! This causes an error!} : { id: number; url: string; xyz: number; } + + id: 1, +>id : number +>1 : 1 + + url: '', +>url : string +>'' : "" + + xyz: 1 // Great! This causes an error! +>xyz : number +>1 : 1 + +}; + +export const myInstance: MyType = { +>myInstance : MyType +>{ id: 1, name: '', photo: { id: 1, url: '', xyz: 2 // This should also be an error }} : { id: number; name: string; photo: { id: number; url: string; xyz: number; }; } + + id: 1, +>id : number +>1 : 1 + + name: '', +>name : string +>'' : "" + + photo: { +>photo : { id: number; url: string; xyz: number; } +>{ id: 1, url: '', xyz: 2 // This should also be an error } : { id: number; url: string; xyz: number; } + + id: 1, +>id : number +>1 : 1 + + url: '', +>url : string +>'' : "" + + xyz: 2 // This should also be an error +>xyz : number +>2 : 2 + } +}; + +// https://github.com/Microsoft/TypeScript/issues/28616 + +export type View = { [K in keyof T]: T[K] extends object ? boolean | View : boolean }; +>View : View + +interface TypeC { + foo: string; +>foo : string + + bar: string; +>bar : string +} + +interface TypeB { + foo: string, +>foo : string + + bar: TypeC +>bar : TypeC +} + +interface TypeA { + foo: string, +>foo : string + + bar: TypeB, +>bar : TypeB +} + +let test: View; +>test : View + +test = { foo: true, bar: true, boo: true } +>test = { foo: true, bar: true, boo: true } : { foo: true; bar: true; boo: boolean; } +>test : View +>{ foo: true, bar: true, boo: true } : { foo: true; bar: true; boo: boolean; } +>foo : true +>true : true +>bar : true +>true : true +>boo : boolean +>true : true + +test = { foo: true, bar: { foo: true, bar: true, boo: true } } +>test = { foo: true, bar: { foo: true, bar: true, boo: true } } : { foo: true; bar: { foo: true; bar: true; boo: boolean; }; } +>test : View +>{ foo: true, bar: { foo: true, bar: true, boo: true } } : { foo: true; bar: { foo: true; bar: true; boo: boolean; }; } +>foo : true +>true : true +>bar : { foo: true; bar: true; boo: boolean; } +>{ foo: true, bar: true, boo: true } : { foo: true; bar: true; boo: boolean; } +>foo : true +>true : true +>bar : true +>true : true +>boo : boolean +>true : true + diff --git a/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.errors.txt b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.errors.txt new file mode 100644 index 0000000000000..4cf8a99e0eafb --- /dev/null +++ b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.errors.txt @@ -0,0 +1,44 @@ +tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts(13,35): error TS2322: Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'number | IProps'. + Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'. +tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts(16,7): error TS2322: Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'number | IProps'. + Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'IProps'. + Types of property 'nestedProp' are incompatible. + Type '{ asdfasdf: string; }' has no properties in common with type '{ testBool?: boolean; }'. +tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts(19,56): error TS2326: Types of property 'nestedProps' are incompatible. + Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'IProps'. + Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'. + + +==== tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts (3 errors) ==== + interface IProps { + iconProp?: string; + nestedProp?: { + testBool?: boolean; + } + } + + interface INestedProps { + nestedProps?: IProps; + } + + // These are the types of errors we want: + const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'number | IProps'. +!!! error TS2322: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'. + + // Nested typing works here and we also get an expected error: + const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' }; + ~~~~~~ +!!! error TS2322: Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'number | IProps'. +!!! error TS2322: Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'IProps'. +!!! error TS2322: Types of property 'nestedProp' are incompatible. +!!! error TS2322: Type '{ asdfasdf: string; }' has no properties in common with type '{ testBool?: boolean; }'. + + // Want an error generated here but there isn't one. + const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2326: Types of property 'nestedProps' are incompatible. +!!! error TS2326: Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'IProps'. +!!! error TS2326: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'. + \ No newline at end of file diff --git a/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.js b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.js new file mode 100644 index 0000000000000..b286049e4a450 --- /dev/null +++ b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.js @@ -0,0 +1,29 @@ +//// [nonObjectUnionNestedExcessPropertyCheck.ts] +interface IProps { + iconProp?: string; + nestedProp?: { + testBool?: boolean; + } +} + +interface INestedProps { + nestedProps?: IProps; +} + +// These are the types of errors we want: +const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' }; + +// Nested typing works here and we also get an expected error: +const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' }; + +// Want an error generated here but there isn't one. +const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } }; + + +//// [nonObjectUnionNestedExcessPropertyCheck.js] +// These are the types of errors we want: +var propB1 = { INVALID_PROP_NAME: 'share', iconProp: 'test' }; +// Nested typing works here and we also get an expected error: +var propB2 = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' }; +// Want an error generated here but there isn't one. +var propA1 = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } }; diff --git a/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.symbols b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.symbols new file mode 100644 index 0000000000000..95e6c33a64e0f --- /dev/null +++ b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.symbols @@ -0,0 +1,46 @@ +=== tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts === +interface IProps { +>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0)) + + iconProp?: string; +>iconProp : Symbol(IProps.iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 18)) + + nestedProp?: { +>nestedProp : Symbol(IProps.nestedProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 1, 22)) + + testBool?: boolean; +>testBool : Symbol(testBool, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 2, 18)) + } +} + +interface INestedProps { +>INestedProps : Symbol(INestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 5, 1)) + + nestedProps?: IProps; +>nestedProps : Symbol(INestedProps.nestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 7, 24)) +>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0)) +} + +// These are the types of errors we want: +const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' }; +>propB1 : Symbol(propB1, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 12, 5)) +>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0)) +>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 12, 33)) +>iconProp : Symbol(iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 12, 61)) + +// Nested typing works here and we also get an expected error: +const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' }; +>propB2 : Symbol(propB2, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 5)) +>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0)) +>nestedProp : Symbol(nestedProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 33)) +>asdfasdf : Symbol(asdfasdf, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 47)) +>iconProp : Symbol(iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 67)) + +// Want an error generated here but there isn't one. +const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } }; +>propA1 : Symbol(propA1, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 5)) +>INestedProps : Symbol(INestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 5, 1)) +>nestedProps : Symbol(nestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 39)) +>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 54)) +>iconProp : Symbol(iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 82)) + diff --git a/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.types b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.types new file mode 100644 index 0000000000000..3e05dbd362853 --- /dev/null +++ b/tests/baselines/reference/nonObjectUnionNestedExcessPropertyCheck.types @@ -0,0 +1,49 @@ +=== tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts === +interface IProps { + iconProp?: string; +>iconProp : string + + nestedProp?: { +>nestedProp : { testBool?: boolean; } + + testBool?: boolean; +>testBool : boolean + } +} + +interface INestedProps { + nestedProps?: IProps; +>nestedProps : IProps +} + +// These are the types of errors we want: +const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' }; +>propB1 : number | IProps +>{ INVALID_PROP_NAME: 'share', iconProp: 'test' } : { INVALID_PROP_NAME: string; iconProp: string; } +>INVALID_PROP_NAME : string +>'share' : "share" +>iconProp : string +>'test' : "test" + +// Nested typing works here and we also get an expected error: +const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' }; +>propB2 : number | IProps +>{ nestedProp: { asdfasdf: 'test' }, iconProp: 'test' } : { nestedProp: { asdfasdf: string; }; iconProp: string; } +>nestedProp : { asdfasdf: string; } +>{ asdfasdf: 'test' } : { asdfasdf: string; } +>asdfasdf : string +>'test' : "test" +>iconProp : string +>'test' : "test" + +// Want an error generated here but there isn't one. +const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } }; +>propA1 : number | INestedProps +>{ nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } } : { nestedProps: { INVALID_PROP_NAME: string; iconProp: string; }; } +>nestedProps : { INVALID_PROP_NAME: string; iconProp: string; } +>{ INVALID_PROP_NAME: 'share', iconProp: 'test' } : { INVALID_PROP_NAME: string; iconProp: string; } +>INVALID_PROP_NAME : string +>'share' : "share" +>iconProp : string +>'test' : "test" + diff --git a/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.js b/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.js new file mode 100644 index 0000000000000..fa9960719231b --- /dev/null +++ b/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.js @@ -0,0 +1,17 @@ +//// [unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts] +interface IStringDictionary { + [name: string]: V; +} +interface INumberDictionary { + [idx: number]: V; +} + +declare function forEach(from: IStringDictionary | INumberDictionary, callback: (entry: { key: any; value: T; }, remove: () => void) => any); + +let count = 0; +forEach({ toString: 123 }, () => count++); + + +//// [unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.js] +var count = 0; +forEach({ toString: 123 }, function () { return count++; }); diff --git a/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.symbols b/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.symbols new file mode 100644 index 0000000000000..f671260a7a35c --- /dev/null +++ b/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.symbols @@ -0,0 +1,41 @@ +=== tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts === +interface IStringDictionary { +>IStringDictionary : Symbol(IStringDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 0)) +>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 28)) + + [name: string]: V; +>name : Symbol(name, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 1, 2)) +>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 28)) +} +interface INumberDictionary { +>INumberDictionary : Symbol(INumberDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 2, 1)) +>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 3, 28)) + + [idx: number]: V; +>idx : Symbol(idx, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 4, 2)) +>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 3, 28)) +} + +declare function forEach(from: IStringDictionary | INumberDictionary, callback: (entry: { key: any; value: T; }, remove: () => void) => any); +>forEach : Symbol(forEach, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 5, 1)) +>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25)) +>from : Symbol(from, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 28)) +>IStringDictionary : Symbol(IStringDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 0)) +>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25)) +>INumberDictionary : Symbol(INumberDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 2, 1)) +>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25)) +>callback : Symbol(callback, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 78)) +>entry : Symbol(entry, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 90)) +>key : Symbol(key, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 98)) +>value : Symbol(value, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 108)) +>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25)) +>remove : Symbol(remove, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 121)) + +let count = 0; +>count : Symbol(count, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 9, 3)) + +forEach({ toString: 123 }, () => count++); +>forEach : Symbol(forEach, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 5, 1)) +>toString : Symbol(toString, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 10, 9)) +>count : Symbol(count, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 9, 3)) + diff --git a/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.types b/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.types new file mode 100644 index 0000000000000..83bd83d6ec176 --- /dev/null +++ b/tests/baselines/reference/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts === +interface IStringDictionary { + [name: string]: V; +>name : string +} +interface INumberDictionary { + [idx: number]: V; +>idx : number +} + +declare function forEach(from: IStringDictionary | INumberDictionary, callback: (entry: { key: any; value: T; }, remove: () => void) => any); +>forEach : (from: IStringDictionary | INumberDictionary, callback: (entry: { key: any; value: T; }, remove: () => void) => any) => any +>from : IStringDictionary | INumberDictionary +>callback : (entry: { key: any; value: T; }, remove: () => void) => any +>entry : { key: any; value: T; } +>key : any +>value : T +>remove : () => void + +let count = 0; +>count : number +>0 : 0 + +forEach({ toString: 123 }, () => count++); +>forEach({ toString: 123 }, () => count++) : any +>forEach : (from: IStringDictionary | INumberDictionary, callback: (entry: { key: any; value: T; }, remove: () => void) => any) => any +>{ toString: 123 } : { toString: number; } +>toString : number +>123 : 123 +>() => count++ : () => number +>count++ : number +>count : number + diff --git a/tests/baselines/reference/unionExcessPropsWithPartialMember.js b/tests/baselines/reference/unionExcessPropsWithPartialMember.js new file mode 100644 index 0000000000000..cefd480bba81a --- /dev/null +++ b/tests/baselines/reference/unionExcessPropsWithPartialMember.js @@ -0,0 +1,31 @@ +//// [unionExcessPropsWithPartialMember.ts] +interface A { + unused?: string; + x: string; +} + +interface B { + x: string; + y: string; +} + +declare var ab: A | B; +declare var a: A; + +ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A` + + +//// [unionExcessPropsWithPartialMember.js] +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +ab = __assign({}, a, { y: null }); // Should be allowed, since `y` is missing on `A` diff --git a/tests/baselines/reference/unionExcessPropsWithPartialMember.symbols b/tests/baselines/reference/unionExcessPropsWithPartialMember.symbols new file mode 100644 index 0000000000000..a81636816a527 --- /dev/null +++ b/tests/baselines/reference/unionExcessPropsWithPartialMember.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/unionExcessPropsWithPartialMember.ts === +interface A { +>A : Symbol(A, Decl(unionExcessPropsWithPartialMember.ts, 0, 0)) + + unused?: string; +>unused : Symbol(A.unused, Decl(unionExcessPropsWithPartialMember.ts, 0, 13)) + + x: string; +>x : Symbol(A.x, Decl(unionExcessPropsWithPartialMember.ts, 1, 20)) +} + +interface B { +>B : Symbol(B, Decl(unionExcessPropsWithPartialMember.ts, 3, 1)) + + x: string; +>x : Symbol(B.x, Decl(unionExcessPropsWithPartialMember.ts, 5, 13)) + + y: string; +>y : Symbol(B.y, Decl(unionExcessPropsWithPartialMember.ts, 6, 14)) +} + +declare var ab: A | B; +>ab : Symbol(ab, Decl(unionExcessPropsWithPartialMember.ts, 10, 11)) +>A : Symbol(A, Decl(unionExcessPropsWithPartialMember.ts, 0, 0)) +>B : Symbol(B, Decl(unionExcessPropsWithPartialMember.ts, 3, 1)) + +declare var a: A; +>a : Symbol(a, Decl(unionExcessPropsWithPartialMember.ts, 11, 11)) +>A : Symbol(A, Decl(unionExcessPropsWithPartialMember.ts, 0, 0)) + +ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A` +>ab : Symbol(ab, Decl(unionExcessPropsWithPartialMember.ts, 10, 11)) +>a : Symbol(a, Decl(unionExcessPropsWithPartialMember.ts, 11, 11)) +>y : Symbol(y, Decl(unionExcessPropsWithPartialMember.ts, 13, 11)) + diff --git a/tests/baselines/reference/unionExcessPropsWithPartialMember.types b/tests/baselines/reference/unionExcessPropsWithPartialMember.types new file mode 100644 index 0000000000000..2c3460d977c07 --- /dev/null +++ b/tests/baselines/reference/unionExcessPropsWithPartialMember.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/unionExcessPropsWithPartialMember.ts === +interface A { + unused?: string; +>unused : string | undefined + + x: string; +>x : string +} + +interface B { + x: string; +>x : string + + y: string; +>y : string +} + +declare var ab: A | B; +>ab : A | B + +declare var a: A; +>a : A + +ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A` +>ab = {...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string | undefined; x: string; } +>ab : A | B +>{...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string | undefined; x: string; } +>a : A +>y : string | undefined +>(null as any as string | undefined) : string | undefined +>null as any as string | undefined : string | undefined +>null as any : any +>null : null + diff --git a/tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts b/tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts new file mode 100644 index 0000000000000..ba7c2cf29d991 --- /dev/null +++ b/tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts @@ -0,0 +1,27 @@ +interface StatelessComponent

{ + (props: P & { children?: number }, context?: any): null; +} + +const TestComponent: StatelessComponent = (props) => { + return null; +} + +interface ITestProps { + ariaLabel?: string; +} + +interface NestedProp { + props: TProps; +} + +interface TestProps { + icon: NestedProp; +} + +TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); + +const TestComponent2: StatelessComponent = (props) => { + return null; +} + +TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); diff --git a/tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts b/tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts new file mode 100644 index 0000000000000..86bf8f6261c96 --- /dev/null +++ b/tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts @@ -0,0 +1,70 @@ +// https://github.com/Microsoft/TypeScript/issues/13813 + +interface A { + x: string +} + +interface B { + a: A; +} + +interface C { + c: number; +} + +type D = B & C; + +let a: B = { a: { x: 'hello' } }; // ok +let b: B = { a: { x: 2 } }; // error - types of property x are incompatible +let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A + +let d: D = { a: { x: 'hello' }, c: 5 }; // ok +let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible +let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error + +// https://github.com/Microsoft/TypeScript/issues/18075 + +export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } } + +export let obj: MyType; + +export const photo: typeof obj.photo = { + id: 1, + url: '', + xyz: 1 // Great! This causes an error! +}; + +export const myInstance: MyType = { + id: 1, + name: '', + photo: { + id: 1, + url: '', + xyz: 2 // This should also be an error + } +}; + +// https://github.com/Microsoft/TypeScript/issues/28616 + +export type View = { [K in keyof T]: T[K] extends object ? boolean | View : boolean }; + +interface TypeC { + foo: string; + bar: string; +} + +interface TypeB { + foo: string, + bar: TypeC +} + +interface TypeA { + foo: string, + bar: TypeB, +} + +let test: View; + +test = { foo: true, bar: true, boo: true } + +test = { foo: true, bar: { foo: true, bar: true, boo: true } } diff --git a/tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts b/tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts new file mode 100644 index 0000000000000..5050d33c05eb4 --- /dev/null +++ b/tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts @@ -0,0 +1,19 @@ +interface IProps { + iconProp?: string; + nestedProp?: { + testBool?: boolean; + } +} + +interface INestedProps { + nestedProps?: IProps; +} + +// These are the types of errors we want: +const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' }; + +// Nested typing works here and we also get an expected error: +const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' }; + +// Want an error generated here but there isn't one. +const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } }; diff --git a/tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts b/tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts new file mode 100644 index 0000000000000..757c0f9917b37 --- /dev/null +++ b/tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts @@ -0,0 +1,11 @@ +interface IStringDictionary { + [name: string]: V; +} +interface INumberDictionary { + [idx: number]: V; +} + +declare function forEach(from: IStringDictionary | INumberDictionary, callback: (entry: { key: any; value: T; }, remove: () => void) => any); + +let count = 0; +forEach({ toString: 123 }, () => count++); diff --git a/tests/cases/compiler/unionExcessPropsWithPartialMember.ts b/tests/cases/compiler/unionExcessPropsWithPartialMember.ts new file mode 100644 index 0000000000000..05f0475e0d05e --- /dev/null +++ b/tests/cases/compiler/unionExcessPropsWithPartialMember.ts @@ -0,0 +1,15 @@ +// @strict: true +interface A { + unused?: string; + x: string; +} + +interface B { + x: string; + y: string; +} + +declare var ab: A | B; +declare var a: A; + +ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A` From 3af78ae77a2db85e6955b0a26216965737036317 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 16 Apr 2019 12:22:42 -0700 Subject: [PATCH 10/16] Revert and always use merged symbol to get members of late bound symbol Fixes #30891 --- src/compiler/checker.ts | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5c2745ab3e740..b8ac6aeaf5042 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6607,11 +6607,12 @@ namespace ts { * unique symbol type which we can then use as the name of the member. This allows users * to define custom symbols that can be used in the members of an object type. * + * @param parent The containing symbol for the member. * @param earlySymbols The early-bound symbols of the parent. * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { + function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -6642,7 +6643,6 @@ namespace ts { } lateSymbol.nameType = type; addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); - const parent = getSymbolOfNode(decl.parent); if (lateSymbol.parent) { Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); } @@ -6652,15 +6652,6 @@ namespace ts { return links.resolvedSymbol = lateSymbol; } } - else { - const type = checkComputedPropertyName(decl.name); - if (isTypeUsableAsPropertyName(type)) { - const memberName = getPropertyNameFromType(type); - if (!lateSymbols.has(memberName)) { - lateSymbols.set(memberName, links.resolvedSymbol); - } - } - } return links.resolvedSymbol; } @@ -6684,7 +6675,7 @@ namespace ts { if (members) { for (const member of members) { if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { - lateBindMember(earlySymbols, lateSymbols, member); + lateBindMember(symbol, earlySymbols, lateSymbols, member); } } } @@ -6718,11 +6709,12 @@ namespace ts { const links = getSymbolLinks(symbol); if (!links.lateSymbol && some(symbol.declarations, hasLateBindableName)) { // force late binding of members/exports. This will set the late-bound symbol + const parent = getMergedSymbol(symbol.parent)!; if (some(symbol.declarations, hasStaticModifier)) { - getExportsOfSymbol(symbol.parent!); + getExportsOfSymbol(parent); } else { - getMembersOfSymbol(symbol.parent!); + getMembersOfSymbol(parent); } } return links.lateSymbol || (links.lateSymbol = symbol); From 50fdeccd7f0380b995932151c09c27baff2591e5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 17 Apr 2019 13:58:05 -0700 Subject: [PATCH 11/16] One more iteration --- src/compiler/checker.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e047c00d9531f..5673b8b8089d4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14960,9 +14960,11 @@ namespace ts { } // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. - const indexInfo = getIndexInfoOfType(source, IndexKind.String) || getNonEnumNumberIndexInfo(source); - const sourcePropsType = indexInfo && indexInfo.type || getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)); - inferFromTypes(sourcePropsType, getTemplateTypeFromMappedType(target)); + const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol); + const stringIndexType = getIndexTypeOfType(source, IndexKind.String); + const numberIndexInfo = getNonEnumNumberIndexInfo(source); + const numberIndexType = numberIndexInfo && numberIndexInfo.type; + inferFromTypes(getUnionType(append(append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target)); return true; } return false; From 4420d1083b052da55ac294bae9948370bc257119 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 17 Apr 2019 14:32:18 -0700 Subject: [PATCH 12/16] Add diagnostics for relation cache size (#30999) * Add diagnostics for relation cache size * Move to extendedDiagnostics * Single method that returns a 3-property object * Fix double-space lint --- src/compiler/checker.ts | 5 +++++ src/compiler/program.ts | 1 + src/compiler/types.ts | 2 ++ src/tsc/tsc.ts | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0c91e1ba06208..48a9c2e745cd8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -114,6 +114,11 @@ namespace ts { getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"), getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount") + symbolCount, getTypeCount: () => typeCount, + getRelationCacheSizes: () => ({ + assignable: assignableRelation.size, + identity: identityRelation.size, + subtype: subtypeRelation.size, + }), isUndefinedSymbol: symbol => symbol === undefinedSymbol, isArgumentsSymbol: symbol => symbol === argumentsSymbol, isUnknownSymbol: symbol => symbol === unknownSymbol, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 74bb8e1b1c817..4f50aa3ab1f59 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -927,6 +927,7 @@ namespace ts { getIdentifierCount: () => getDiagnosticsProducingTypeChecker().getIdentifierCount(), getSymbolCount: () => getDiagnosticsProducingTypeChecker().getSymbolCount(), getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(), + getRelationCacheSizes: () => getDiagnosticsProducingTypeChecker().getRelationCacheSizes(), getFileProcessingDiagnostics: () => fileProcessingDiagnostics, getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives, isSourceFileFromExternalLibrary, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6fba5f149cf53..1e50c59fc9d99 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2961,6 +2961,7 @@ namespace ts { /* @internal */ getIdentifierCount(): number; /* @internal */ getSymbolCount(): number; /* @internal */ getTypeCount(): number; + /* @internal */ getRelationCacheSizes(): { assignable: number, identity: number, subtype: number }; /* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection; /* @internal */ getResolvedTypeReferenceDirectives(): Map; @@ -3246,6 +3247,7 @@ namespace ts { /* @internal */ getIdentifierCount(): number; /* @internal */ getSymbolCount(): number; /* @internal */ getTypeCount(): number; + /* @internal */ getRelationCacheSizes(): { assignable: number, identity: number, subtype: number }; /* @internal */ isArrayType(type: Type): boolean; /* @internal */ isTupleType(type: Type): boolean; diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 984ebe21cf6e6..500480463bdbb 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -340,6 +340,10 @@ namespace ts { const checkTime = performance.getDuration("Check"); const emitTime = performance.getDuration("Emit"); if (compilerOptions.extendedDiagnostics) { + const caches = program.getRelationCacheSizes(); + reportCountStatistic("Assignability cache size", caches.assignable); + reportCountStatistic("Identity cache size", caches.identity); + reportCountStatistic("Subtype cache size", caches.subtype); performance.forEachMeasure((name, duration) => reportTimeStatistic(`${name} time`, duration)); } else { From d919f2c113da9a18140577d1278508fe522ba0f7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 17 Apr 2019 15:13:09 -0700 Subject: [PATCH 13/16] Add test for #28334 --- ...olAssignmentOnGlobalAugmentationSuceeds.js | 18 ++++++++++++ ...ignmentOnGlobalAugmentationSuceeds.symbols | 29 +++++++++++++++++++ ...ssignmentOnGlobalAugmentationSuceeds.types | 28 ++++++++++++++++++ ...olAssignmentOnGlobalAugmentationSuceeds.ts | 13 +++++++++ 4 files changed, 88 insertions(+) create mode 100644 tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js create mode 100644 tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols create mode 100644 tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types create mode 100644 tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts diff --git a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js new file mode 100644 index 0000000000000..bfb6f0a29c7af --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js @@ -0,0 +1,18 @@ +//// [uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts] +const FOO_SYMBOL = Symbol('Foo'); + +declare global { + interface Promise { + [FOO_SYMBOL]?: number; + } +} + +export function foo(p: Promise) { + p[FOO_SYMBOL] = 3; +} + +//// [uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js] +const FOO_SYMBOL = Symbol('Foo'); +export function foo(p) { + p[FOO_SYMBOL] = 3; +} diff --git a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols new file mode 100644 index 0000000000000..17af30e8facf1 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts === +const FOO_SYMBOL = Symbol('Foo'); +>FOO_SYMBOL : Symbol(FOO_SYMBOL, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +declare global { +>global : Symbol(global, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 33)) + + interface Promise { +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 2, 16)) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 3, 22)) + + [FOO_SYMBOL]?: number; +>[FOO_SYMBOL] : Symbol(Promise[FOO_SYMBOL], Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 3, 26)) +>FOO_SYMBOL : Symbol(FOO_SYMBOL, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 5)) + } +} + +export function foo(p: Promise) { +>foo : Symbol(foo, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 6, 1)) +>T : Symbol(T, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 20)) +>p : Symbol(p, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 2, 16)) +>T : Symbol(T, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 20)) + + p[FOO_SYMBOL] = 3; +>p : Symbol(p, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 23)) +>FOO_SYMBOL : Symbol(FOO_SYMBOL, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 5)) +} diff --git a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types new file mode 100644 index 0000000000000..62dcc0607ae33 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts === +const FOO_SYMBOL = Symbol('Foo'); +>FOO_SYMBOL : unique symbol +>Symbol('Foo') : unique symbol +>Symbol : SymbolConstructor +>'Foo' : "Foo" + +declare global { +>global : any + + interface Promise { + [FOO_SYMBOL]?: number; +>[FOO_SYMBOL] : number | undefined +>FOO_SYMBOL : unique symbol + } +} + +export function foo(p: Promise) { +>foo : (p: Promise) => void +>p : Promise + + p[FOO_SYMBOL] = 3; +>p[FOO_SYMBOL] = 3 : 3 +>p[FOO_SYMBOL] : number | undefined +>p : Promise +>FOO_SYMBOL : unique symbol +>3 : 3 +} diff --git a/tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts b/tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts new file mode 100644 index 0000000000000..f79c2a36e8608 --- /dev/null +++ b/tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts @@ -0,0 +1,13 @@ +// @strict: true +// @target: es6 +const FOO_SYMBOL = Symbol('Foo'); + +declare global { + interface Promise { + [FOO_SYMBOL]?: number; + } +} + +export function foo(p: Promise) { + p[FOO_SYMBOL] = 3; +} \ No newline at end of file From dc7d77f2c7f6406eeddc207d9ad87534e9d57fec Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 17 Apr 2019 15:08:40 -0700 Subject: [PATCH 14/16] Make the tsbuild tests use simple libFile instead of bigger lib file set --- src/testRunner/unittests/tsbuild/helpers.ts | 17 ++---- src/testRunner/unittests/tsbuild/sample.ts | 6 +- .../unittests/tsbuild/transitiveReferences.ts | 10 ++-- .../incremental-declaration-changes/sample.js | 60 ------------------- .../when-declaration-option-changes.js | 20 ------- ...en-logic-config-changes-declaration-dir.js | 40 ------------- .../sample.js | 20 ------- .../tsbuild/sample1/initial-Build/sample.js | 60 ------------------- .../when-declaration-option-changes.js | 20 ------- ...en-logic-config-changes-declaration-dir.js | 60 ------------------- .../when-logic-specifies-tsBuildInfoFile.js | 60 ------------------- .../tsconfig_withFiles.json | 1 - .../tsconfig_withInclude.json | 1 - .../tsconfig_withIncludeAndFiles.json | 1 - .../tsconfig_withIncludeOfJson.json | 1 - 15 files changed, 14 insertions(+), 363 deletions(-) diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 538ebd75cdb8a..6c6510cd7b5a2 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -62,31 +62,26 @@ namespace ts { } } + const libContent = `${TestFSWithWatch.libFile.content} +interface ReadonlyArray {} +declare const console: { log(msg: any): void; };`; + export function loadProjectFromDisk(root: string, time?: vfs.FileSystemOptions["time"]): vfs.FileSystem { const resolver = vfs.createResolver(Harness.IO); const fs = new vfs.FileSystem(/*ignoreCase*/ true, { files: { - ["/lib"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), "built/local"), resolver), ["/src"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), root), resolver) }, cwd: "/", meta: { defaultLibLocation: "/lib" }, time }); + fs.mkdirSync("/lib"); + fs.writeFileSync("/lib/lib.d.ts", libContent); fs.makeReadonly(); return fs; } - export function getLibs() { - return [ - "/lib/lib.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.webworker.importscripts.d.ts", - "/lib/lib.scripthost.d.ts" - ]; - } - function generateSourceMapBaselineFiles(fs: vfs.FileSystem, mapFileNames: ReadonlyArray) { for (const mapFile of mapFileNames) { if (!fs.existsSync(mapFile)) continue; diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index ab9210451aa99..6e31ada9ee575 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -399,14 +399,14 @@ export class cNew {}`); const builder = createSolutionBuilder(host, ["/src/tests"], { listFiles: true }); builder.buildAllProjects(); assert.deepEqual(host.traces, [ - ...getLibs(), + "/lib/lib.d.ts", "/src/core/anotherModule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts", - ...getLibs(), + "/lib/lib.d.ts", ...getCoreOutputs(), "/src/logic/index.ts", - ...getLibs(), + "/lib/lib.d.ts", ...getCoreOutputs(), "/src/logic/index.d.ts", "/src/tests/index.ts" diff --git a/src/testRunner/unittests/tsbuild/transitiveReferences.ts b/src/testRunner/unittests/tsbuild/transitiveReferences.ts index 7944d1fda0968..30e28de8cdec2 100644 --- a/src/testRunner/unittests/tsbuild/transitiveReferences.ts +++ b/src/testRunner/unittests/tsbuild/transitiveReferences.ts @@ -7,12 +7,12 @@ namespace ts { "/src/c.js" ]; const expectedFileTraces = [ - ...getLibs(), + "/lib/lib.d.ts", "/src/a.ts", - ...getLibs(), + "/lib/lib.d.ts", "/src/a.d.ts", "/src/b.ts", - ...getLibs(), + "/lib/lib.d.ts", "/src/a.d.ts", "/src/b.d.ts", "/src/refs/a.d.ts", @@ -63,9 +63,9 @@ export const b = new A();`); // Error in b build only a const allExpectedOutputs = ["/src/a.js", "/src/a.d.ts"]; const expectedFileTraces = [ - ...getLibs(), + "/lib/lib.d.ts", "/src/a.ts", - ...getLibs(), + "/lib/lib.d.ts", "/src/b.ts" ]; verifyBuild(fs => modifyFsBTsToNonRelativeImport(fs, "node"), diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js index c1274f3f49f41..02f3fe6e91afb 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js @@ -175,22 +175,6 @@ export class someClass { } "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/anothermodule.ts": { "version": "-2676574883", "signature": "25219880154" @@ -215,10 +199,6 @@ export class someClass { } "exportedModulesMap": {}, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts" @@ -235,22 +215,6 @@ export class someClass { } "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-2069755619", "signature": "-2069755619" @@ -285,10 +249,6 @@ export class someClass { } }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts" @@ -305,22 +265,6 @@ export class someClass { } "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-2069755619", "signature": "-2069755619" @@ -365,10 +309,6 @@ export class someClass { } }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts", diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js index ad16296e10cf1..43e463e4d63a7 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js @@ -24,22 +24,6 @@ export declare function multiply(a: number, b: number): number; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/anothermodule.ts": { "version": "-2676574883", "signature": "-8396256275" @@ -63,10 +47,6 @@ export declare function multiply(a: number, b: number): number; "exportedModulesMap": {}, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts" diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js index 3412d1c89a20d..2189fcd394a57 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js @@ -28,22 +28,6 @@ export declare const m: typeof mod; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -79,10 +63,6 @@ export declare const m: typeof mod; }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts" @@ -99,22 +79,6 @@ export declare const m: typeof mod; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -159,10 +123,6 @@ export declare const m: typeof mod; }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts", diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js index 85fcc62cfc9c0..cee10f6866b64 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js @@ -28,22 +28,6 @@ class someClass { } "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/anothermodule.ts": { "version": "-2676574883", "signature": "25219880154" @@ -68,10 +52,6 @@ class someClass { } "exportedModulesMap": {}, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts" diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js index 21e8c9b820f4b..2d22389340f94 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js @@ -188,22 +188,6 @@ exports.multiply = multiply; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/anothermodule.ts": { "version": "-2676574883", "signature": "25219880154" @@ -228,10 +212,6 @@ exports.multiply = multiply; "exportedModulesMap": {}, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts" @@ -393,22 +373,6 @@ sourceFile:index.ts "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -443,10 +407,6 @@ sourceFile:index.ts }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts" @@ -479,22 +439,6 @@ exports.m = mod; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -539,10 +483,6 @@ exports.m = mod; }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts", diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js index 341b277de0dcb..4641a3fd0d85e 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js @@ -30,22 +30,6 @@ exports.multiply = multiply; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/anothermodule.ts": { "version": "-2676574883", "signature": "-8396256275" @@ -68,10 +52,6 @@ exports.multiply = multiply; "exportedModulesMap": {}, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts" diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js index 21e8c9b820f4b..2d22389340f94 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js @@ -188,22 +188,6 @@ exports.multiply = multiply; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/anothermodule.ts": { "version": "-2676574883", "signature": "25219880154" @@ -228,10 +212,6 @@ exports.multiply = multiply; "exportedModulesMap": {}, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts" @@ -393,22 +373,6 @@ sourceFile:index.ts "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -443,10 +407,6 @@ sourceFile:index.ts }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts" @@ -479,22 +439,6 @@ exports.m = mod; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -539,10 +483,6 @@ exports.m = mod; }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts", diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js index 990a019c479b5..cde5b25ae0e28 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js @@ -188,22 +188,6 @@ exports.multiply = multiply; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/anothermodule.ts": { "version": "-2676574883", "signature": "25219880154" @@ -228,10 +212,6 @@ exports.multiply = multiply; "exportedModulesMap": {}, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/core/some_decl.d.ts" @@ -393,22 +373,6 @@ sourceFile:index.ts "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -444,10 +408,6 @@ sourceFile:index.ts }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts" @@ -496,22 +456,6 @@ exports.m = mod; "version": "/lib/lib.d.ts", "signature": "/lib/lib.d.ts" }, - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" - }, - "/lib/lib.dom.d.ts": { - "version": "/lib/lib.dom.d.ts", - "signature": "/lib/lib.dom.d.ts" - }, - "/lib/lib.webworker.importscripts.d.ts": { - "version": "/lib/lib.webworker.importscripts.d.ts", - "signature": "/lib/lib.webworker.importscripts.d.ts" - }, - "/lib/lib.scripthost.d.ts": { - "version": "/lib/lib.scripthost.d.ts", - "signature": "/lib/lib.scripthost.d.ts" - }, "/src/core/index.ts": { "version": "-13851440507", "signature": "-13851440507" @@ -556,10 +500,6 @@ exports.m = mod; }, "semanticDiagnosticsPerFile": [ "/lib/lib.d.ts", - "/lib/lib.dom.d.ts", - "/lib/lib.es5.d.ts", - "/lib/lib.scripthost.d.ts", - "/lib/lib.webworker.importscripts.d.ts", "/src/core/anothermodule.ts", "/src/core/index.ts", "/src/logic/index.ts", diff --git a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withFiles.json b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withFiles.json index 71097850dbf5c..e463caf4879ae 100644 --- a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withFiles.json +++ b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withFiles.json @@ -1,7 +1,6 @@ { "compilerOptions": { "composite": true, - "target": "esnext", "moduleResolution": "node", "module": "commonjs", "resolveJsonModule": true, diff --git a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withInclude.json b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withInclude.json index 5efdbe28ac49b..dde5eec33c415 100644 --- a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withInclude.json +++ b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withInclude.json @@ -1,7 +1,6 @@ { "compilerOptions": { "composite": true, - "target": "esnext", "moduleResolution": "node", "module": "commonjs", "resolveJsonModule": true, diff --git a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeAndFiles.json b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeAndFiles.json index f50c629bac579..82da9b398a740 100644 --- a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeAndFiles.json +++ b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeAndFiles.json @@ -1,7 +1,6 @@ { "compilerOptions": { "composite": true, - "target": "esnext", "moduleResolution": "node", "module": "commonjs", "resolveJsonModule": true, diff --git a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeOfJson.json b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeOfJson.json index 72d960b6fba40..47279604fa683 100644 --- a/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeOfJson.json +++ b/tests/projects/resolveJsonModuleAndComposite/tsconfig_withIncludeOfJson.json @@ -1,7 +1,6 @@ { "compilerOptions": { "composite": true, - "target": "esnext", "moduleResolution": "node", "module": "commonjs", "resolveJsonModule": true, From acbedade4249934c6061a716625920ec97dc10d9 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 17 Apr 2019 15:36:47 -0700 Subject: [PATCH 15/16] No need to fix hash of lib files since the content is now fixed --- src/harness/fakes.ts | 22 ------------------- .../incremental-declaration-changes/sample.js | 12 +++++----- .../when-declaration-option-changes.js | 4 ++-- ...en-logic-config-changes-declaration-dir.js | 8 +++---- .../sample.js | 4 ++-- .../tsbuild/sample1/initial-Build/sample.js | 12 +++++----- .../when-declaration-option-changes.js | 4 ++-- ...en-logic-config-changes-declaration-dir.js | 12 +++++----- .../when-logic-specifies-tsBuildInfoFile.js | 12 +++++----- 9 files changed, 34 insertions(+), 56 deletions(-) diff --git a/src/harness/fakes.ts b/src/harness/fakes.ts index dcc125698c859..489a41dd677d7 100644 --- a/src/harness/fakes.ts +++ b/src/harness/fakes.ts @@ -397,19 +397,6 @@ namespace fakes { const value = super.readFile(path); if (!value || !ts.isBuildInfoFile(path)) return value; const buildInfo = ts.getBuildInfo(value); - if (buildInfo.program) { - // Fix lib signatures - for (const path of ts.getOwnKeys(buildInfo.program.fileInfos)) { - if (ts.startsWith(path, "/lib/")) { - const currentValue = buildInfo.program.fileInfos[path]; - ts.Debug.assert(currentValue.signature === path); - ts.Debug.assert(currentValue.signature === currentValue.version); - const text = super.readFile(path)!; - const signature = ts.generateDjb2Hash(text); - buildInfo.program.fileInfos[path] = { version: signature, signature }; - } - } - } ts.Debug.assert(buildInfo.version === version); buildInfo.version = ts.version; return ts.getBuildInfoText(buildInfo); @@ -419,15 +406,6 @@ namespace fakes { if (!ts.isBuildInfoFile(fileName)) return super.writeFile(fileName, content, writeByteOrderMark); const buildInfo = ts.getBuildInfo(content); if (buildInfo.program) { - // Fix lib signatures - for (const path of ts.getOwnKeys(buildInfo.program.fileInfos)) { - if (ts.startsWith(path, "/lib/")) { - const currentValue = buildInfo.program.fileInfos[path]; - ts.Debug.assert(currentValue.signature === currentValue.version); - buildInfo.program.fileInfos[path] = { version: path, signature: path }; - } - } - // reference Map if (buildInfo.program.referencedMap) { const referencedMap: ts.MapLike = {}; diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js index 02f3fe6e91afb..a698d6c34cfc6 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/sample.js @@ -172,8 +172,8 @@ export class someClass { } "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/anothermodule.ts": { "version": "-2676574883", @@ -212,8 +212,8 @@ export class someClass { } "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-2069755619", @@ -262,8 +262,8 @@ export class someClass { } "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-2069755619", diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js index 43e463e4d63a7..69c7b20d5068e 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-declaration-option-changes.js @@ -21,8 +21,8 @@ export declare function multiply(a: number, b: number): number; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/anothermodule.ts": { "version": "-2676574883", diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js index 2189fcd394a57..53f222a4bf510 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-logic-config-changes-declaration-dir.js @@ -25,8 +25,8 @@ export declare const m: typeof mod; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", @@ -76,8 +76,8 @@ export declare const m: typeof mod; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js index cee10f6866b64..aae81ea9fdcac 100644 --- a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-doesnt-change/sample.js @@ -25,8 +25,8 @@ class someClass { } "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/anothermodule.ts": { "version": "-2676574883", diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js index 2d22389340f94..ef63741766af9 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/sample.js @@ -185,8 +185,8 @@ exports.multiply = multiply; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/anothermodule.ts": { "version": "-2676574883", @@ -370,8 +370,8 @@ sourceFile:index.ts "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", @@ -436,8 +436,8 @@ exports.m = mod; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js index 4641a3fd0d85e..90f10c0a25c4c 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-declaration-option-changes.js @@ -27,8 +27,8 @@ exports.multiply = multiply; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/anothermodule.ts": { "version": "-2676574883", diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js index 2d22389340f94..ef63741766af9 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-config-changes-declaration-dir.js @@ -185,8 +185,8 @@ exports.multiply = multiply; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/anothermodule.ts": { "version": "-2676574883", @@ -370,8 +370,8 @@ sourceFile:index.ts "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", @@ -436,8 +436,8 @@ exports.m = mod; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js index cde5b25ae0e28..b3b74cb388c9a 100644 --- a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-logic-specifies-tsBuildInfoFile.js @@ -185,8 +185,8 @@ exports.multiply = multiply; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/anothermodule.ts": { "version": "-2676574883", @@ -370,8 +370,8 @@ sourceFile:index.ts "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", @@ -453,8 +453,8 @@ exports.m = mod; "program": { "fileInfos": { "/lib/lib.d.ts": { - "version": "/lib/lib.d.ts", - "signature": "/lib/lib.d.ts" + "version": "-15964756381", + "signature": "-15964756381" }, "/src/core/index.ts": { "version": "-13851440507", From 83941c46553ec0ce7102d5e4507dde412377335a Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 17 Apr 2019 16:19:34 -0700 Subject: [PATCH 16/16] Fix lateBoundSymbol test case to handle the simple lib file for the test --- ...s-merged-and-contains-late-bound-member.js | 64 +++---------------- ...s-merged-and-contains-late-bound-member.js | 64 +++---------------- .../projects/lateBoundSymbol/src/globals.d.ts | 4 ++ tests/projects/lateBoundSymbol/tsconfig.json | 3 - 4 files changed, 20 insertions(+), 115 deletions(-) create mode 100644 tests/projects/lateBoundSymbol/src/globals.d.ts diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js index 89748694bbc31..b0549b1a8fb4e 100644 --- a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js @@ -21,49 +21,13 @@ type A = HKT[typeof sym]; { "program": { "fileInfos": { - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" + "/lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" }, - "/lib/lib.es2015.d.ts": { - "version": "/lib/lib.es2015.d.ts", - "signature": "/lib/lib.es2015.d.ts" - }, - "/lib/lib.es2015.core.d.ts": { - "version": "/lib/lib.es2015.core.d.ts", - "signature": "/lib/lib.es2015.core.d.ts" - }, - "/lib/lib.es2015.collection.d.ts": { - "version": "/lib/lib.es2015.collection.d.ts", - "signature": "/lib/lib.es2015.collection.d.ts" - }, - "/lib/lib.es2015.generator.d.ts": { - "version": "/lib/lib.es2015.generator.d.ts", - "signature": "/lib/lib.es2015.generator.d.ts" - }, - "/lib/lib.es2015.iterable.d.ts": { - "version": "/lib/lib.es2015.iterable.d.ts", - "signature": "/lib/lib.es2015.iterable.d.ts" - }, - "/lib/lib.es2015.promise.d.ts": { - "version": "/lib/lib.es2015.promise.d.ts", - "signature": "/lib/lib.es2015.promise.d.ts" - }, - "/lib/lib.es2015.proxy.d.ts": { - "version": "/lib/lib.es2015.proxy.d.ts", - "signature": "/lib/lib.es2015.proxy.d.ts" - }, - "/lib/lib.es2015.reflect.d.ts": { - "version": "/lib/lib.es2015.reflect.d.ts", - "signature": "/lib/lib.es2015.reflect.d.ts" - }, - "/lib/lib.es2015.symbol.d.ts": { - "version": "/lib/lib.es2015.symbol.d.ts", - "signature": "/lib/lib.es2015.symbol.d.ts" - }, - "/lib/lib.es2015.symbol.wellknown.d.ts": { - "version": "/lib/lib.es2015.symbol.wellknown.d.ts", - "signature": "/lib/lib.es2015.symbol.wellknown.d.ts" + "/src/src/globals.d.ts": { + "version": "-1994196675", + "signature": "-1994196675" }, "/src/src/hkt.ts": { "version": "675797797", @@ -76,9 +40,6 @@ type A = HKT[typeof sym]; }, "options": { "rootDir": "/src/src", - "lib": [ - "lib.es2015.d.ts" - ], "incremental": true, "configFilePath": "/src/tsconfig.json" }, @@ -93,17 +54,8 @@ type A = HKT[typeof sym]; ] }, "semanticDiagnosticsPerFile": [ - "/lib/lib.es2015.collection.d.ts", - "/lib/lib.es2015.core.d.ts", - "/lib/lib.es2015.d.ts", - "/lib/lib.es2015.generator.d.ts", - "/lib/lib.es2015.iterable.d.ts", - "/lib/lib.es2015.promise.d.ts", - "/lib/lib.es2015.proxy.d.ts", - "/lib/lib.es2015.reflect.d.ts", - "/lib/lib.es2015.symbol.d.ts", - "/lib/lib.es2015.symbol.wellknown.d.ts", - "/lib/lib.es5.d.ts", + "/lib/lib.d.ts", + "/src/src/globals.d.ts", "/src/src/hkt.ts", "/src/src/main.ts" ] diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js index e30b62fcca876..a48d6df88e45c 100644 --- a/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js @@ -14,49 +14,13 @@ var x = 10; { "program": { "fileInfos": { - "/lib/lib.es5.d.ts": { - "version": "/lib/lib.es5.d.ts", - "signature": "/lib/lib.es5.d.ts" + "/lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" }, - "/lib/lib.es2015.d.ts": { - "version": "/lib/lib.es2015.d.ts", - "signature": "/lib/lib.es2015.d.ts" - }, - "/lib/lib.es2015.core.d.ts": { - "version": "/lib/lib.es2015.core.d.ts", - "signature": "/lib/lib.es2015.core.d.ts" - }, - "/lib/lib.es2015.collection.d.ts": { - "version": "/lib/lib.es2015.collection.d.ts", - "signature": "/lib/lib.es2015.collection.d.ts" - }, - "/lib/lib.es2015.generator.d.ts": { - "version": "/lib/lib.es2015.generator.d.ts", - "signature": "/lib/lib.es2015.generator.d.ts" - }, - "/lib/lib.es2015.iterable.d.ts": { - "version": "/lib/lib.es2015.iterable.d.ts", - "signature": "/lib/lib.es2015.iterable.d.ts" - }, - "/lib/lib.es2015.promise.d.ts": { - "version": "/lib/lib.es2015.promise.d.ts", - "signature": "/lib/lib.es2015.promise.d.ts" - }, - "/lib/lib.es2015.proxy.d.ts": { - "version": "/lib/lib.es2015.proxy.d.ts", - "signature": "/lib/lib.es2015.proxy.d.ts" - }, - "/lib/lib.es2015.reflect.d.ts": { - "version": "/lib/lib.es2015.reflect.d.ts", - "signature": "/lib/lib.es2015.reflect.d.ts" - }, - "/lib/lib.es2015.symbol.d.ts": { - "version": "/lib/lib.es2015.symbol.d.ts", - "signature": "/lib/lib.es2015.symbol.d.ts" - }, - "/lib/lib.es2015.symbol.wellknown.d.ts": { - "version": "/lib/lib.es2015.symbol.wellknown.d.ts", - "signature": "/lib/lib.es2015.symbol.wellknown.d.ts" + "/src/src/globals.d.ts": { + "version": "-1994196675", + "signature": "-1994196675" }, "/src/src/hkt.ts": { "version": "675797797", @@ -69,9 +33,6 @@ var x = 10; }, "options": { "rootDir": "/src/src", - "lib": [ - "lib.es2015.d.ts" - ], "incremental": true, "configFilePath": "/src/tsconfig.json" }, @@ -86,17 +47,8 @@ var x = 10; ] }, "semanticDiagnosticsPerFile": [ - "/lib/lib.es2015.collection.d.ts", - "/lib/lib.es2015.core.d.ts", - "/lib/lib.es2015.d.ts", - "/lib/lib.es2015.generator.d.ts", - "/lib/lib.es2015.iterable.d.ts", - "/lib/lib.es2015.promise.d.ts", - "/lib/lib.es2015.proxy.d.ts", - "/lib/lib.es2015.reflect.d.ts", - "/lib/lib.es2015.symbol.d.ts", - "/lib/lib.es2015.symbol.wellknown.d.ts", - "/lib/lib.es5.d.ts", + "/lib/lib.d.ts", + "/src/src/globals.d.ts", "/src/src/hkt.ts", "/src/src/main.ts" ] diff --git a/tests/projects/lateBoundSymbol/src/globals.d.ts b/tests/projects/lateBoundSymbol/src/globals.d.ts new file mode 100644 index 0000000000000..8100e5859afb4 --- /dev/null +++ b/tests/projects/lateBoundSymbol/src/globals.d.ts @@ -0,0 +1,4 @@ +interface SymbolConstructor { + (description?: string | number): symbol; +} +declare var Symbol: SymbolConstructor; \ No newline at end of file diff --git a/tests/projects/lateBoundSymbol/tsconfig.json b/tests/projects/lateBoundSymbol/tsconfig.json index 78bf9e23f0086..6146e91d1f3a4 100644 --- a/tests/projects/lateBoundSymbol/tsconfig.json +++ b/tests/projects/lateBoundSymbol/tsconfig.json @@ -1,9 +1,6 @@ { "compilerOptions": { "rootDir": "src", - "lib": [ - "es2015" - ], "incremental": true } } \ No newline at end of file