From 6911acf80b712051db3833162eb68c3d3f79d13c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 14:28:46 -0700 Subject: [PATCH 1/2] Remove freshness from literal types in intersections --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09354d957a3..7c8386e5580 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7589,11 +7589,11 @@ namespace ts { } } - // Add the given types to the given type set. Order is preserved, duplicates are removed, - // and nested types of the given kind are flattened into the set. + // Add the given types to the given type set. Order is preserved, freshness is removed from literal + // types, duplicates are removed, and nested types of the given kind are flattened into the set. function addTypesToIntersection(typeSet: TypeSet, types: Type[]) { for (const type of types) { - addTypeToIntersection(typeSet, type); + addTypeToIntersection(typeSet, getRegularTypeOfLiteralType(type)); } } From 18b5ade05d8ddfb9cce0d9d750a1da394337c904 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 14:48:34 -0700 Subject: [PATCH 2/2] Add regression test --- .../freshLiteralTypesInIntersections.js | 13 ++++++++ .../freshLiteralTypesInIntersections.symbols | 23 ++++++++++++++ .../freshLiteralTypesInIntersections.types | 30 +++++++++++++++++++ .../freshLiteralTypesInIntersections.ts | 7 +++++ 4 files changed, 73 insertions(+) create mode 100644 tests/baselines/reference/freshLiteralTypesInIntersections.js create mode 100644 tests/baselines/reference/freshLiteralTypesInIntersections.symbols create mode 100644 tests/baselines/reference/freshLiteralTypesInIntersections.types create mode 100644 tests/cases/compiler/freshLiteralTypesInIntersections.ts diff --git a/tests/baselines/reference/freshLiteralTypesInIntersections.js b/tests/baselines/reference/freshLiteralTypesInIntersections.js new file mode 100644 index 00000000000..633a2200380 --- /dev/null +++ b/tests/baselines/reference/freshLiteralTypesInIntersections.js @@ -0,0 +1,13 @@ +//// [freshLiteralTypesInIntersections.ts] +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +const q = func("x" as "x" | "y", ["x"]); +q("x"); + + +//// [freshLiteralTypesInIntersections.js] +"use strict"; +// Repro from #19657 +var q = func("x", ["x"]); +q("x"); diff --git a/tests/baselines/reference/freshLiteralTypesInIntersections.symbols b/tests/baselines/reference/freshLiteralTypesInIntersections.symbols new file mode 100644 index 00000000000..b16f90407b4 --- /dev/null +++ b/tests/baselines/reference/freshLiteralTypesInIntersections.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/freshLiteralTypesInIntersections.ts === +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +>func : Symbol(func, Decl(freshLiteralTypesInIntersections.ts, 0, 0)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>B : Symbol(B, Decl(freshLiteralTypesInIntersections.ts, 2, 39)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>a : Symbol(a, Decl(freshLiteralTypesInIntersections.ts, 2, 53)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>b : Symbol(b, Decl(freshLiteralTypesInIntersections.ts, 2, 58)) +>B : Symbol(B, Decl(freshLiteralTypesInIntersections.ts, 2, 39)) +>ab : Symbol(ab, Decl(freshLiteralTypesInIntersections.ts, 2, 69)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>B : Symbol(B, Decl(freshLiteralTypesInIntersections.ts, 2, 39)) + +const q = func("x" as "x" | "y", ["x"]); +>q : Symbol(q, Decl(freshLiteralTypesInIntersections.ts, 3, 5)) +>func : Symbol(func, Decl(freshLiteralTypesInIntersections.ts, 0, 0)) + +q("x"); +>q : Symbol(q, Decl(freshLiteralTypesInIntersections.ts, 3, 5)) + diff --git a/tests/baselines/reference/freshLiteralTypesInIntersections.types b/tests/baselines/reference/freshLiteralTypesInIntersections.types new file mode 100644 index 00000000000..b693a8c2c3f --- /dev/null +++ b/tests/baselines/reference/freshLiteralTypesInIntersections.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/freshLiteralTypesInIntersections.ts === +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +>func : (a: A, b: B[]) => (ab: A & B) => void +>A : A +>B : B +>A : A +>a : A +>A : A +>b : B[] +>B : B +>ab : A & B +>A : A +>B : B + +const q = func("x" as "x" | "y", ["x"]); +>q : (ab: "x") => void +>func("x" as "x" | "y", ["x"]) : (ab: "x") => void +>func : (a: A, b: B[]) => (ab: A & B) => void +>"x" as "x" | "y" : "x" | "y" +>"x" : "x" +>["x"] : "x"[] +>"x" : "x" + +q("x"); +>q("x") : void +>q : (ab: "x") => void +>"x" : "x" + diff --git a/tests/cases/compiler/freshLiteralTypesInIntersections.ts b/tests/cases/compiler/freshLiteralTypesInIntersections.ts new file mode 100644 index 00000000000..b1e73974426 --- /dev/null +++ b/tests/cases/compiler/freshLiteralTypesInIntersections.ts @@ -0,0 +1,7 @@ +// @strict: true + +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +const q = func("x" as "x" | "y", ["x"]); +q("x");