From d4c9f24577517fb1af5274f7e0e6c1e9ca828f0b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 9 Jun 2019 07:46:13 -0700 Subject: [PATCH 1/7] Intersections of disjoint types become never upon construction --- src/compiler/checker.ts | 60 +++++++++++++++++------------------------ src/compiler/types.ts | 2 +- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff2360d57a011..856e6bcd5d43b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9522,44 +9522,13 @@ namespace ts { return false; } - // Return true if the given intersection type contains - // more than one unit type or, - // an object type and a nullable type (null or undefined), or - // a string-like type and a type known to be non-string-like, or - // a number-like type and a type known to be non-number-like, or - // a symbol-like type and a type known to be non-symbol-like, or - // a void-like type and a type known to be non-void-like, or - // a non-primitive type and a type known to be primitive. - function isEmptyIntersectionType(type: IntersectionType) { - let combined: TypeFlags = 0; - for (const t of type.types) { - if (t.flags & TypeFlags.Unit && combined & TypeFlags.Unit) { - return true; - } - combined |= t.flags; - if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive) || - combined & TypeFlags.NonPrimitive && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) || - combined & TypeFlags.StringLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) || - combined & TypeFlags.NumberLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) || - combined & TypeFlags.BigIntLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) || - combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) || - combined & TypeFlags.VoidLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) { - return true; - } - } - return false; - } - function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) { const flags = type.flags; if (flags & TypeFlags.Union) { return addTypesToUnion(typeSet, includes, (type).types); } - // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are - // another form of 'never' (in that they have an empty value domain). We could in theory turn - // intersections of unit types into 'never' upon construction, but deferring the reduction makes it - // easier to reason about their origin. - if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(type))) { + // We ignore 'never' types in unions + if (!(flags & TypeFlags.Never)) { includes |= flags & TypeFlags.IncludesMask; if (flags & TypeFlags.StructuredOrInstantiable) includes |= TypeFlags.IncludesStructuredOrInstantiable; if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; @@ -9783,13 +9752,18 @@ namespace ts { } } else { - includes |= flags & TypeFlags.IncludesMask; if (flags & TypeFlags.AnyOrUnknown) { if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; } else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { + if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) { + // We have seen two distinct unit types which means we should reduce to an + // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen. + includes |= TypeFlags.NonPrimitive; + } typeSet.push(type); } + includes |= flags & TypeFlags.IncludesMask; } return includes; } @@ -9905,7 +9879,23 @@ namespace ts { function getIntersectionType(types: ReadonlyArray, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray): Type { const typeSet: Type[] = []; const includes = addTypesToIntersection(typeSet, 0, types); - if (includes & TypeFlags.Never) { + // An intersection type is considered empty if it contains + // the type never, or + // more than one unit type or, + // an object type and a nullable type (null or undefined), or + // a string-like type and a type known to be non-string-like, or + // a number-like type and a type known to be non-number-like, or + // a symbol-like type and a type known to be non-symbol-like, or + // a void-like type and a type known to be non-void-like, or + // a non-primitive type and a type known to be primitive. + if (includes & TypeFlags.Never || + includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || + includes & TypeFlags.NonPrimitive && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) || + includes & TypeFlags.StringLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) || + includes & TypeFlags.NumberLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) || + includes & TypeFlags.BigIntLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) || + includes & TypeFlags.ESSymbolLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) || + includes & TypeFlags.VoidLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) { return neverType; } if (includes & TypeFlags.Any) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a7ee1c5745fb8..e00f6c6f8e5fb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3983,7 +3983,7 @@ namespace ts { NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable, // The following flags are aggregated during union and intersection type construction /* @internal */ - IncludesMask = Any | Unknown | Primitive | Never | Object | Union, + IncludesMask = Any | Unknown | Primitive | Never | Object | Union | NonPrimitive, // The following flags are used for different purposes during union and intersection type construction /* @internal */ IncludesStructuredOrInstantiable = TypeParameter, From 9cc9fb9bd761cd19b363fe232b8a1d0ef1ed1feb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 9 Jun 2019 08:00:01 -0700 Subject: [PATCH 2/7] Update tests --- tests/cases/conformance/types/conditional/inferTypes1.ts | 2 +- .../types/intersection/intersectionReduction.ts | 8 ++++---- .../types/intersection/intersectionTypeInference2.ts | 4 ++-- .../types/keyof/keyofAndIndexedAccessErrors.ts | 2 +- .../typeInference/unionAndIntersectionInference2.ts | 4 ++-- tests/cases/conformance/types/unknown/unknownType1.ts | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/cases/conformance/types/conditional/inferTypes1.ts b/tests/cases/conformance/types/conditional/inferTypes1.ts index 83d6bd0c0b317..3be629b86ba88 100644 --- a/tests/cases/conformance/types/conditional/inferTypes1.ts +++ b/tests/cases/conformance/types/conditional/inferTypes1.ts @@ -71,7 +71,7 @@ type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U type T50 = X3<{}>; // never type T51 = X3<{ a: (x: string) => void }>; // never type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string -type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number type T60 = infer U; // Error diff --git a/tests/cases/conformance/types/intersection/intersectionReduction.ts b/tests/cases/conformance/types/intersection/intersectionReduction.ts index b3b8950c33064..a6d2bf556b345 100644 --- a/tests/cases/conformance/types/intersection/intersectionReduction.ts +++ b/tests/cases/conformance/types/intersection/intersectionReduction.ts @@ -4,12 +4,12 @@ declare const sym1: unique symbol; declare const sym2: unique symbol; type T1 = string & 'a'; // 'a' -type T2 = 'a' & string & 'b'; // 'a' & 'b' +type T2 = 'a' & string & 'b'; // never type T3 = number & 10; // 10 -type T4 = 10 & number & 20; // 10 & 20 +type T4 = 10 & number & 20; // never type T5 = symbol & typeof sym1; // typeof sym1 -type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 -type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 +type T6 = typeof sym1 & symbol & typeof sym2; // never +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never type T10 = string & ('a' | 'b'); // 'a' | 'b' type T11 = (string | number) & ('a' | 10); // 'a' | 10 diff --git a/tests/cases/conformance/types/intersection/intersectionTypeInference2.ts b/tests/cases/conformance/types/intersection/intersectionTypeInference2.ts index d32441cfee83a..d4ed0d9f970f5 100644 --- a/tests/cases/conformance/types/intersection/intersectionTypeInference2.ts +++ b/tests/cases/conformance/types/intersection/intersectionTypeInference2.ts @@ -3,8 +3,8 @@ declare function f(x: { prop: T }): T; declare const a: { prop: string } & { prop: number }; declare const b: { prop: string & number }; -f(a); // string & number -f(b); // string & number +f(a); // never +f(b); // never // Repro from #18354 diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts index d5fe7c24b5c66..a8666841c85b1 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts @@ -27,7 +27,7 @@ type T17 = Shape[void]; // Error type T18 = Shape[undefined]; // Error type T19 = Shape[{ x: string }]; // Error type T20 = Shape[string | number]; // Error -type T21 = Shape[string & number]; // Error +type T21 = Shape[string & number]; type T22 = Shape[string | boolean]; // Error type T30 = string[]["length"]; diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference2.ts b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference2.ts index 1b6a928ce028c..274b46e3ad657 100644 --- a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference2.ts +++ b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference2.ts @@ -19,5 +19,5 @@ var c2: string & { name: string } & number; var d2: string & { name: string } & number & { name: string }; f2(a2); // string f2(b2); // string[] -f2(c2); // string & number -f2(d2); // string & number +f2(c2); // never +f2(d2); // never diff --git a/tests/cases/conformance/types/unknown/unknownType1.ts b/tests/cases/conformance/types/unknown/unknownType1.ts index 633b1407f9686..f96d1bb32c69b 100644 --- a/tests/cases/conformance/types/unknown/unknownType1.ts +++ b/tests/cases/conformance/types/unknown/unknownType1.ts @@ -4,7 +4,7 @@ type T00 = unknown & null; // null type T01 = unknown & undefined; // undefined -type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) +type T02 = unknown & null & undefined; // never type T03 = unknown & string; // string type T04 = unknown & string[]; // string[] type T05 = unknown & unknown; // unknown From d872b3a9d1afd445442d5990cbe245235d23b8a3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 9 Jun 2019 08:15:38 -0700 Subject: [PATCH 3/7] Accept new baselines --- .../reference/indexingTypesWithNever.types | 4 +-- .../reference/inferTypes1.errors.txt | 2 +- tests/baselines/reference/inferTypes1.js | 2 +- tests/baselines/reference/inferTypes1.symbols | 2 +- tests/baselines/reference/inferTypes1.types | 4 +-- .../reference/intersectionReduction.js | 8 ++--- .../reference/intersectionReduction.symbols | 8 ++--- .../reference/intersectionReduction.types | 16 +++++----- .../reference/intersectionTypeInference2.js | 8 ++--- .../intersectionTypeInference2.symbols | 4 +-- .../intersectionTypeInference2.types | 14 ++++----- .../keyofAndIndexedAccess2.errors.txt | 12 +++----- .../reference/keyofAndIndexedAccess2.types | 2 +- .../keyofAndIndexedAccessErrors.errors.txt | 7 ++--- .../reference/keyofAndIndexedAccessErrors.js | 2 +- .../keyofAndIndexedAccessErrors.symbols | 2 +- .../keyofAndIndexedAccessErrors.types | 4 +-- .../nonPrimitiveUnionIntersection.errors.txt | 12 +++----- .../nonPrimitiveUnionIntersection.types | 8 ++--- tests/baselines/reference/restUnion3.types | 4 +-- ...itchCaseWithIntersectionTypes01.errors.txt | 30 ------------------- .../switchCaseWithIntersectionTypes01.types | 6 ++-- .../reference/tsxUnionElementType3.errors.txt | 6 ++-- .../reference/tsxUnionElementType4.errors.txt | 6 ++-- ...ypeGuardNarrowsPrimitiveIntersection.types | 12 ++++---- .../unionAndIntersectionInference2.js | 8 ++--- .../unionAndIntersectionInference2.symbols | 4 +-- .../unionAndIntersectionInference2.types | 16 +++++----- .../unionTypeCallSignatures.errors.txt | 12 +++----- .../unionTypeConstructSignatures.errors.txt | 12 +++----- .../reference/unionTypeMembers.errors.txt | 10 +++---- .../reference/unknownType1.errors.txt | 2 +- tests/baselines/reference/unknownType1.js | 2 +- .../baselines/reference/unknownType1.symbols | 2 +- tests/baselines/reference/unknownType1.types | 4 +-- 35 files changed, 101 insertions(+), 156 deletions(-) delete mode 100644 tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt diff --git a/tests/baselines/reference/indexingTypesWithNever.types b/tests/baselines/reference/indexingTypesWithNever.types index bf141ae0059e4..c8e2afdabdc12 100644 --- a/tests/baselines/reference/indexingTypesWithNever.types +++ b/tests/baselines/reference/indexingTypesWithNever.types @@ -69,8 +69,8 @@ declare function genericFn3< // Should be never const result5 = genericFn3({ g: "gtest", h: "htest" }, "g", "h"); // 'g' & 'h' will reduce to never ->result5 : unknown ->genericFn3({ g: "gtest", h: "htest" }, "g", "h") : unknown +>result5 : never +>genericFn3({ g: "gtest", h: "htest" }, "g", "h") : never >genericFn3 : (obj: T, u: U, v: V) => T[U & V] >{ g: "gtest", h: "htest" } : { g: string; h: string; } >g : string diff --git a/tests/baselines/reference/inferTypes1.errors.txt b/tests/baselines/reference/inferTypes1.errors.txt index 1de0ca2562f8a..3779d91bf2b01 100644 --- a/tests/baselines/reference/inferTypes1.errors.txt +++ b/tests/baselines/reference/inferTypes1.errors.txt @@ -107,7 +107,7 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(145,40): error TS2322: type T50 = X3<{}>; // never type T51 = X3<{ a: (x: string) => void }>; // never type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string - type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number + type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number type T60 = infer U; // Error diff --git a/tests/baselines/reference/inferTypes1.js b/tests/baselines/reference/inferTypes1.js index d15933264e934..01dc5a797f224 100644 --- a/tests/baselines/reference/inferTypes1.js +++ b/tests/baselines/reference/inferTypes1.js @@ -69,7 +69,7 @@ type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U type T50 = X3<{}>; // never type T51 = X3<{ a: (x: string) => void }>; // never type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string -type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number type T60 = infer U; // Error diff --git a/tests/baselines/reference/inferTypes1.symbols b/tests/baselines/reference/inferTypes1.symbols index 6abd0a2a36c23..609a0093290a7 100644 --- a/tests/baselines/reference/inferTypes1.symbols +++ b/tests/baselines/reference/inferTypes1.symbols @@ -297,7 +297,7 @@ type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string >b : Symbol(b, Decl(inferTypes1.ts, 69, 39)) >x : Symbol(x, Decl(inferTypes1.ts, 69, 44)) -type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never >T53 : Symbol(T53, Decl(inferTypes1.ts, 69, 66)) >X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) >a : Symbol(a, Decl(inferTypes1.ts, 70, 15)) diff --git a/tests/baselines/reference/inferTypes1.types b/tests/baselines/reference/inferTypes1.types index 149ee287d6b6b..2696b520ae8a4 100644 --- a/tests/baselines/reference/inferTypes1.types +++ b/tests/baselines/reference/inferTypes1.types @@ -211,8 +211,8 @@ type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string >b : (x: string) => void >x : string -type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number ->T53 : number & string +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never +>T53 : never >a : (x: number) => void >x : number >b : (x: string) => void diff --git a/tests/baselines/reference/intersectionReduction.js b/tests/baselines/reference/intersectionReduction.js index 1b985a79b9f83..ba0c3cea77564 100644 --- a/tests/baselines/reference/intersectionReduction.js +++ b/tests/baselines/reference/intersectionReduction.js @@ -5,12 +5,12 @@ declare const sym1: unique symbol; declare const sym2: unique symbol; type T1 = string & 'a'; // 'a' -type T2 = 'a' & string & 'b'; // 'a' & 'b' +type T2 = 'a' & string & 'b'; // never type T3 = number & 10; // 10 -type T4 = 10 & number & 20; // 10 & 20 +type T4 = 10 & number & 20; // never type T5 = symbol & typeof sym1; // typeof sym1 -type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 -type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 +type T6 = typeof sym1 & symbol & typeof sym2; // never +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never type T10 = string & ('a' | 'b'); // 'a' | 'b' type T11 = (string | number) & ('a' | 10); // 'a' | 10 diff --git a/tests/baselines/reference/intersectionReduction.symbols b/tests/baselines/reference/intersectionReduction.symbols index 607ea1d6c480d..e932e3eb6c680 100644 --- a/tests/baselines/reference/intersectionReduction.symbols +++ b/tests/baselines/reference/intersectionReduction.symbols @@ -10,25 +10,25 @@ declare const sym2: unique symbol; type T1 = string & 'a'; // 'a' >T1 : Symbol(T1, Decl(intersectionReduction.ts, 3, 34)) -type T2 = 'a' & string & 'b'; // 'a' & 'b' +type T2 = 'a' & string & 'b'; // never >T2 : Symbol(T2, Decl(intersectionReduction.ts, 5, 23)) type T3 = number & 10; // 10 >T3 : Symbol(T3, Decl(intersectionReduction.ts, 6, 29)) -type T4 = 10 & number & 20; // 10 & 20 +type T4 = 10 & number & 20; // never >T4 : Symbol(T4, Decl(intersectionReduction.ts, 7, 22)) type T5 = symbol & typeof sym1; // typeof sym1 >T5 : Symbol(T5, Decl(intersectionReduction.ts, 8, 27)) >sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) -type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 +type T6 = typeof sym1 & symbol & typeof sym2; // never >T6 : Symbol(T6, Decl(intersectionReduction.ts, 9, 31)) >sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) >sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13)) -type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never >T7 : Symbol(T7, Decl(intersectionReduction.ts, 10, 45)) >sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) diff --git a/tests/baselines/reference/intersectionReduction.types b/tests/baselines/reference/intersectionReduction.types index f8c178cfca43f..725e1b5629ea3 100644 --- a/tests/baselines/reference/intersectionReduction.types +++ b/tests/baselines/reference/intersectionReduction.types @@ -10,26 +10,26 @@ declare const sym2: unique symbol; type T1 = string & 'a'; // 'a' >T1 : "a" -type T2 = 'a' & string & 'b'; // 'a' & 'b' ->T2 : T2 +type T2 = 'a' & string & 'b'; // never +>T2 : never type T3 = number & 10; // 10 >T3 : 10 -type T4 = 10 & number & 20; // 10 & 20 ->T4 : T4 +type T4 = 10 & number & 20; // never +>T4 : never type T5 = symbol & typeof sym1; // typeof sym1 >T5 : unique symbol >sym1 : unique symbol -type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 ->T6 : T6 +type T6 = typeof sym1 & symbol & typeof sym2; // never +>T6 : never >sym1 : unique symbol >sym2 : unique symbol -type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 ->T7 : T7 +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never +>T7 : never >sym1 : unique symbol type T10 = string & ('a' | 'b'); // 'a' | 'b' diff --git a/tests/baselines/reference/intersectionTypeInference2.js b/tests/baselines/reference/intersectionTypeInference2.js index 804b8d8520600..806af6872d766 100644 --- a/tests/baselines/reference/intersectionTypeInference2.js +++ b/tests/baselines/reference/intersectionTypeInference2.js @@ -4,8 +4,8 @@ declare function f(x: { prop: T }): T; declare const a: { prop: string } & { prop: number }; declare const b: { prop: string & number }; -f(a); // string & number -f(b); // string & number +f(a); // never +f(b); // never // Repro from #18354 @@ -17,7 +17,7 @@ f2(obj, 'b'); //// [intersectionTypeInference2.js] -f(a); // string & number -f(b); // string & number +f(a); // never +f(b); // never f2(obj, 'a'); f2(obj, 'b'); diff --git a/tests/baselines/reference/intersectionTypeInference2.symbols b/tests/baselines/reference/intersectionTypeInference2.symbols index b04de204de183..20b7d0b1d4cf8 100644 --- a/tests/baselines/reference/intersectionTypeInference2.symbols +++ b/tests/baselines/reference/intersectionTypeInference2.symbols @@ -16,11 +16,11 @@ declare const b: { prop: string & number }; >b : Symbol(b, Decl(intersectionTypeInference2.ts, 3, 13)) >prop : Symbol(prop, Decl(intersectionTypeInference2.ts, 3, 18)) -f(a); // string & number +f(a); // never >f : Symbol(f, Decl(intersectionTypeInference2.ts, 0, 0)) >a : Symbol(a, Decl(intersectionTypeInference2.ts, 2, 13)) -f(b); // string & number +f(b); // never >f : Symbol(f, Decl(intersectionTypeInference2.ts, 0, 0)) >b : Symbol(b, Decl(intersectionTypeInference2.ts, 3, 13)) diff --git a/tests/baselines/reference/intersectionTypeInference2.types b/tests/baselines/reference/intersectionTypeInference2.types index 72f4bf30e1f7a..d34b8545a9f33 100644 --- a/tests/baselines/reference/intersectionTypeInference2.types +++ b/tests/baselines/reference/intersectionTypeInference2.types @@ -10,18 +10,18 @@ declare const a: { prop: string } & { prop: number }; >prop : number declare const b: { prop: string & number }; ->b : { prop: string & number; } ->prop : string & number +>b : { prop: never; } +>prop : never -f(a); // string & number ->f(a) : string & number +f(a); // never +>f(a) : never >f : (x: { prop: T; }) => T >a : { prop: string; } & { prop: number; } -f(b); // string & number ->f(b) : string & number +f(b); // never +>f(b) : never >f : (x: { prop: T; }) => T ->b : { prop: string & number; } +>b : { prop: never; } // Repro from #18354 diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt index fffeac41ff7b5..ff96efe3e13fc 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt @@ -17,8 +17,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(31,5): error TS232 tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(38,5): error TS2322: Type '{ [x: string]: number; }' is not assignable to type '{ [P in K]: number; }'. tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(50,3): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Item'. No index signature with a parameter of type 'string' was found on type 'Item'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(51,3): error TS2322: Type '123' is not assignable to type 'string & number'. - Type '123' is not assignable to type 'string'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(51,3): error TS2322: Type '123' is not assignable to type 'never'. tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(52,3): error TS2322: Type '123' is not assignable to type 'T[keyof T]'. tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(53,3): error TS2322: Type '123' is not assignable to type 'T[K]'. tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(65,7): error TS2339: Property 'foo' does not exist on type 'T'. @@ -26,8 +25,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(66,3): error TS253 tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(67,3): error TS2322: Type '123' is not assignable to type 'T[keyof T]'. tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(68,3): error TS2322: Type '123' is not assignable to type 'T[K]'. tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to type 'Type[K]'. - Type '123' is not assignable to type '123 & "some string"'. - Type '123' is not assignable to type '"some string"'. + Type '123' is not assignable to type 'never'. ==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts (23 errors) ==== @@ -117,8 +115,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23 !!! error TS7053: No index signature with a parameter of type 'string' was found on type 'Item'. obj[k2] = 123; // Error ~~~~~~~ -!!! error TS2322: Type '123' is not assignable to type 'string & number'. -!!! error TS2322: Type '123' is not assignable to type 'string'. +!!! error TS2322: Type '123' is not assignable to type 'never'. obj[k3] = 123; // Error ~~~~~~~ !!! error TS2322: Type '123' is not assignable to type 'T[keyof T]'. @@ -190,8 +187,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23 return 123; // Error ~~~~~~~~~~~ !!! error TS2322: Type '123' is not assignable to type 'Type[K]'. -!!! error TS2322: Type '123' is not assignable to type '123 & "some string"'. -!!! error TS2322: Type '123' is not assignable to type '"some string"'. +!!! error TS2322: Type '123' is not assignable to type 'never'. } // Repro from #30920 diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.types b/tests/baselines/reference/keyofAndIndexedAccess2.types index a6d8315466562..b282588cc5159 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.types +++ b/tests/baselines/reference/keyofAndIndexedAccess2.types @@ -249,7 +249,7 @@ function f10(obj: T, k1: string, k2: keyof It obj[k2] = 123; // Error >obj[k2] = 123 : 123 ->obj[k2] : string & number +>obj[k2] : never >obj : T >k2 : "a" | "b" >123 : 123 diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 68e56efb38ab9..69f992447e8b3 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -10,7 +10,6 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(27,18): error tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(28,18): error TS2538: Type '{ x: string; }' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'number'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(30,18): error TS2538: Type 'string & number' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'false' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'true' cannot be used as an index type. @@ -81,7 +80,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(141,5): error tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error TS2322: Type 'number[]' is not assignable to type 'T[K]'. -==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (41 errors) ==== +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (40 errors) ==== class Shape { name: string; width: number; @@ -135,9 +134,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error !!! error TS2537: Type 'Shape' has no matching index signature for type 'number'. ~~~~~~~~~~~~~~~ !!! error TS2537: Type 'Shape' has no matching index signature for type 'string'. - type T21 = Shape[string & number]; // Error - ~~~~~~~~~~~~~~~ -!!! error TS2538: Type 'string & number' cannot be used as an index type. + type T21 = Shape[string & number]; type T22 = Shape[string | boolean]; // Error ~~~~~~~~~~~~~~~~ !!! error TS2537: Type 'Shape' has no matching index signature for type 'string'. diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.js b/tests/baselines/reference/keyofAndIndexedAccessErrors.js index f262f9a0d3c67..864cd0731ac52 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.js +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.js @@ -28,7 +28,7 @@ type T17 = Shape[void]; // Error type T18 = Shape[undefined]; // Error type T19 = Shape[{ x: string }]; // Error type T20 = Shape[string | number]; // Error -type T21 = Shape[string & number]; // Error +type T21 = Shape[string & number]; type T22 = Shape[string | boolean]; // Error type T30 = string[]["length"]; diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols index 1dd7c0d564828..3c11ae4d744fe 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols @@ -93,7 +93,7 @@ type T20 = Shape[string | number]; // Error >T20 : Symbol(T20, Decl(keyofAndIndexedAccessErrors.ts, 27, 32)) >Shape : Symbol(Shape, Decl(keyofAndIndexedAccessErrors.ts, 0, 0)) -type T21 = Shape[string & number]; // Error +type T21 = Shape[string & number]; >T21 : Symbol(T21, Decl(keyofAndIndexedAccessErrors.ts, 28, 34)) >Shape : Symbol(Shape, Decl(keyofAndIndexedAccessErrors.ts, 0, 0)) diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 780138d6c6bcd..90d2c462d0a69 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -74,8 +74,8 @@ type T19 = Shape[{ x: string }]; // Error type T20 = Shape[string | number]; // Error >T20 : any -type T21 = Shape[string & number]; // Error ->T21 : any +type T21 = Shape[string & number]; +>T21 : never type T22 = Shape[string | boolean]; // Error >T22 : any diff --git a/tests/baselines/reference/nonPrimitiveUnionIntersection.errors.txt b/tests/baselines/reference/nonPrimitiveUnionIntersection.errors.txt index 5aad982dc20f0..38bff6c43198a 100644 --- a/tests/baselines/reference/nonPrimitiveUnionIntersection.errors.txt +++ b/tests/baselines/reference/nonPrimitiveUnionIntersection.errors.txt @@ -1,9 +1,7 @@ -tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(1,5): error TS2322: Type '""' is not assignable to type 'object & string'. - Type '""' is not assignable to type 'object'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(1,5): error TS2322: Type '""' is not assignable to type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(3,5): error TS2322: Type '123' is not assignable to type 'object & {}'. Type '123' is not assignable to type 'object'. -tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(4,1): error TS2322: Type 'string' is not assignable to type 'object & string'. - Type 'string' is not assignable to type 'object'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(4,1): error TS2322: Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38): error TS2322: Type '{ bar: string; }' is not assignable to type 'object & { err: string; }'. Object literal may only specify known properties, and 'bar' does not exist in type 'object & { err: string; }'. @@ -11,8 +9,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38 ==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts (4 errors) ==== var a: object & string = ""; // error ~ -!!! error TS2322: Type '""' is not assignable to type 'object & string'. -!!! error TS2322: Type '""' is not assignable to type 'object'. +!!! error TS2322: Type '""' is not assignable to type 'never'. var b: object | string = ""; // ok var c: object & {} = 123; // error ~ @@ -20,8 +17,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38 !!! error TS2322: Type '123' is not assignable to type 'object'. a = b; // error ~ -!!! error TS2322: Type 'string' is not assignable to type 'object & string'. -!!! error TS2322: Type 'string' is not assignable to type 'object'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. b = a; // ok const foo: object & {} = {bar: 'bar'}; // ok diff --git a/tests/baselines/reference/nonPrimitiveUnionIntersection.types b/tests/baselines/reference/nonPrimitiveUnionIntersection.types index 55a0b2a018c22..ef7e2f8928b93 100644 --- a/tests/baselines/reference/nonPrimitiveUnionIntersection.types +++ b/tests/baselines/reference/nonPrimitiveUnionIntersection.types @@ -1,6 +1,6 @@ === tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts === var a: object & string = ""; // error ->a : object & string +>a : never >"" : "" var b: object | string = ""; // ok @@ -13,13 +13,13 @@ var c: object & {} = 123; // error a = b; // error >a = b : string ->a : object & string +>a : never >b : string b = a; // ok ->b = a : object & string +>b = a : never >b : string | object ->a : object & string +>a : never const foo: object & {} = {bar: 'bar'}; // ok >foo : object & {} diff --git a/tests/baselines/reference/restUnion3.types b/tests/baselines/reference/restUnion3.types index 7c9daafae7904..24bc5e4a52ce4 100644 --- a/tests/baselines/reference/restUnion3.types +++ b/tests/baselines/reference/restUnion3.types @@ -11,7 +11,7 @@ var {...rest4 } = nullAndUndefinedUnion; >nullAndUndefinedUnion : null | undefined declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; ->unionWithIntersection : { n: number; } & { s: string; } & undefined +>unionWithIntersection : never >n : number >s : string @@ -22,5 +22,5 @@ var rest5: { n: number, s: string }; var {...rest5 } = unionWithIntersection; >rest5 : { n: number; s: string; } ->unionWithIntersection : { n: number; } & { s: string; } & undefined +>unionWithIntersection : never diff --git a/tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt b/tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt deleted file mode 100644 index 380e98c3c3ddf..0000000000000 --- a/tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt +++ /dev/null @@ -1,30 +0,0 @@ -tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(22,10): error TS2678: Type 'boolean' is not comparable to type 'string & number'. - - -==== tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts (1 errors) ==== - var strAndNum: string & number; - var numAndBool: number & boolean; - var str: string; - var num: number; - var bool: boolean; - - switch (strAndNum) { - // Identical - case strAndNum: - break; - - // Constituents - case str: - case num: - break; - - // Overlap in constituents - case numAndBool: - break; - - // No relation - case bool: - ~~~~ -!!! error TS2678: Type 'boolean' is not comparable to type 'string & number'. - break; - } \ No newline at end of file diff --git a/tests/baselines/reference/switchCaseWithIntersectionTypes01.types b/tests/baselines/reference/switchCaseWithIntersectionTypes01.types index 9ba884985dc24..d6ba87f1e09fb 100644 --- a/tests/baselines/reference/switchCaseWithIntersectionTypes01.types +++ b/tests/baselines/reference/switchCaseWithIntersectionTypes01.types @@ -1,6 +1,6 @@ === tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts === var strAndNum: string & number; ->strAndNum : string & number +>strAndNum : never var numAndBool: number & boolean; >numAndBool : never @@ -15,11 +15,11 @@ var bool: boolean; >bool : boolean switch (strAndNum) { ->strAndNum : string & number +>strAndNum : never // Identical case strAndNum: ->strAndNum : string & number +>strAndNum : never break; diff --git a/tests/baselines/reference/tsxUnionElementType3.errors.txt b/tests/baselines/reference/tsxUnionElementType3.errors.txt index 8f8ce3c28bd73..73d8ccb0ce2b2 100644 --- a/tests/baselines/reference/tsxUnionElementType3.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType3.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not assignable to type 'number & string'. - Type 'string' is not assignable to type 'number'. +tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not assignable to type 'never'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -36,8 +35,7 @@ tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not // OK let a = ; ~ -!!! error TS2322: Type 'string' is not assignable to type 'number & string'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' let a1 = ; let a2 = ; diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt index 4b059d093f8ff..bca0229de54cf 100644 --- a/tests/baselines/reference/tsxUnionElementType4.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'true' is not assignable to type 'number & string'. - Type 'true' is not assignable to type 'number'. +tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'true' is not assignable to type 'never'. tests/cases/conformance/jsx/file.tsx(33,10): error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. @@ -40,8 +39,7 @@ tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; } // Error let a = ; ~ -!!! error TS2322: Type 'true' is not assignable to type 'number & string'. -!!! error TS2322: Type 'true' is not assignable to type 'number'. +!!! error TS2322: Type 'true' is not assignable to type 'never'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' let b = ~~~~~~~~~~ diff --git a/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.types b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.types index 262568a65cac9..a14629c3e2a9e 100644 --- a/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.types +++ b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.types @@ -40,12 +40,12 @@ const enum Tag2 {} >Tag2 : Tag2 declare function isNonBlank2(value: string) : value is (string & Tag2); ->isNonBlank2 : (value: string) => value is string & Tag2 +>isNonBlank2 : (value: string) => value is never >value : string declare function doThis2(value: string & Tag2): void; ->doThis2 : (value: string & Tag2) => void ->value : string & Tag2 +>doThis2 : (value: never) => void +>value : never declare function doThat2(value: string) : void; >doThat2 : (value: string) => void @@ -53,13 +53,13 @@ declare function doThat2(value: string) : void; if (isNonBlank2(value)) { >isNonBlank2(value) : boolean ->isNonBlank2 : (value: string) => value is string & Tag2 +>isNonBlank2 : (value: string) => value is never >value : string doThis2(value); >doThis2(value) : void ->doThis2 : (value: string & Tag2) => void ->value : string & Tag2 +>doThis2 : (value: never) => void +>value : never } else { doThat2(value); diff --git a/tests/baselines/reference/unionAndIntersectionInference2.js b/tests/baselines/reference/unionAndIntersectionInference2.js index 18f08452a2ef5..8446213b3f1c5 100644 --- a/tests/baselines/reference/unionAndIntersectionInference2.js +++ b/tests/baselines/reference/unionAndIntersectionInference2.js @@ -20,8 +20,8 @@ var c2: string & { name: string } & number; var d2: string & { name: string } & number & { name: string }; f2(a2); // string f2(b2); // string[] -f2(c2); // string & number -f2(d2); // string & number +f2(c2); // never +f2(d2); // never //// [unionAndIntersectionInference2.js] @@ -41,5 +41,5 @@ var c2; var d2; f2(a2); // string f2(b2); // string[] -f2(c2); // string & number -f2(d2); // string & number +f2(c2); // never +f2(d2); // never diff --git a/tests/baselines/reference/unionAndIntersectionInference2.symbols b/tests/baselines/reference/unionAndIntersectionInference2.symbols index 24b1a36aa45e6..926286dde5220 100644 --- a/tests/baselines/reference/unionAndIntersectionInference2.symbols +++ b/tests/baselines/reference/unionAndIntersectionInference2.symbols @@ -75,11 +75,11 @@ f2(b2); // string[] >f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7)) >b2 : Symbol(b2, Decl(unionAndIntersectionInference2.ts, 16, 3)) -f2(c2); // string & number +f2(c2); // never >f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7)) >c2 : Symbol(c2, Decl(unionAndIntersectionInference2.ts, 17, 3)) -f2(d2); // string & number +f2(d2); // never >f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7)) >d2 : Symbol(d2, Decl(unionAndIntersectionInference2.ts, 18, 3)) diff --git a/tests/baselines/reference/unionAndIntersectionInference2.types b/tests/baselines/reference/unionAndIntersectionInference2.types index 0fac3f2fc1b76..a163b25ce2891 100644 --- a/tests/baselines/reference/unionAndIntersectionInference2.types +++ b/tests/baselines/reference/unionAndIntersectionInference2.types @@ -58,11 +58,11 @@ var b2: { name: string } & string[]; >name : string var c2: string & { name: string } & number; ->c2 : string & { name: string; } & number +>c2 : never >name : string var d2: string & { name: string } & number & { name: string }; ->d2 : string & { name: string; } & number & { name: string; } +>d2 : never >name : string >name : string @@ -76,13 +76,13 @@ f2(b2); // string[] >f2 : (x: T & { name: string; }) => T >b2 : { name: string; } & string[] -f2(c2); // string & number ->f2(c2) : string & number +f2(c2); // never +>f2(c2) : never >f2 : (x: T & { name: string; }) => T ->c2 : string & { name: string; } & number +>c2 : never -f2(d2); // string & number ->f2(d2) : string & number +f2(d2); // never +>f2(d2) : never >f2 : (x: T & { name: string; }) => T ->d2 : string & { name: string; } & number & { name: string; } +>d2 : never diff --git a/tests/baselines/reference/unionTypeCallSignatures.errors.txt b/tests/baselines/reference/unionTypeCallSignatures.errors.txt index f7a2c9d076686..2c80ac58cc8f4 100644 --- a/tests/baselines/reference/unionTypeCallSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeCallSignatures.errors.txt @@ -2,10 +2,8 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(9,43): error TS23 tests/cases/conformance/types/union/unionTypeCallSignatures.ts(10,29): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(15,29): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(16,1): error TS2554: Expected 1 arguments, but got 0. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,32): error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. - Type '10' is not assignable to type 'string'. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,32): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. - Type '"hello"' is not assignable to type 'number'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,32): error TS2345: Argument of type '10' is not assignable to parameter of type 'never'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,32): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(21,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(24,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(26,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. @@ -59,12 +57,10 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(73,12): error TS2 var unionOfDifferentParameterTypes: { (a: number): number; } | { (a: string): Date; }; unionOfDifferentParameterTypes(10);// error - no call signatures ~~ -!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. -!!! error TS2345: Type '10' is not assignable to type 'string'. +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'never'. unionOfDifferentParameterTypes("hello");// error - no call signatures ~~~~~~~ -!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. -!!! error TS2345: Type '"hello"' is not assignable to type 'number'. +!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'. unionOfDifferentParameterTypes();// error - no call signatures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2554: Expected 1 arguments, but got 0. diff --git a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt index d420d95f3b157..d46f616e53ef0 100644 --- a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt @@ -2,10 +2,8 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(9,47): error tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(10,33): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(15,33): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(16,1): error TS2554: Expected 1 arguments, but got 0. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,36): error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. - Type '10' is not assignable to type 'string'. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. - Type '"hello"' is not assignable to type 'number'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,36): error TS2345: Argument of type '10' is not assignable to parameter of type 'never'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(21,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(24,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(26,40): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. @@ -58,12 +56,10 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): erro var unionOfDifferentParameterTypes: { new (a: number): number; } | { new (a: string): Date; }; new unionOfDifferentParameterTypes(10);// error - no call signatures ~~ -!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. -!!! error TS2345: Type '10' is not assignable to type 'string'. +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'never'. new unionOfDifferentParameterTypes("hello");// error - no call signatures ~~~~~~~ -!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. -!!! error TS2345: Type '"hello"' is not assignable to type 'number'. +!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'. new unionOfDifferentParameterTypes();// error - no call signatures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2554: Expected 1 arguments, but got 0. diff --git a/tests/baselines/reference/unionTypeMembers.errors.txt b/tests/baselines/reference/unionTypeMembers.errors.txt index 2a2f93d1a071c..8c18e200d916d 100644 --- a/tests/baselines/reference/unionTypeMembers.errors.txt +++ b/tests/baselines/reference/unionTypeMembers.errors.txt @@ -1,6 +1,5 @@ -tests/cases/conformance/types/union/unionTypeMembers.ts(44,38): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string & number'. - Type 'string' is not assignable to type 'string & number'. - Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/union/unionTypeMembers.ts(44,38): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/union/unionTypeMembers.ts(51,3): error TS2339: Property 'propertyOnlyInI1' does not exist on type 'I1 | I2'. Property 'propertyOnlyInI1' does not exist on type 'I2'. tests/cases/conformance/types/union/unionTypeMembers.ts(52,3): error TS2339: Property 'propertyOnlyInI2' does not exist on type 'I1 | I2'. @@ -57,9 +56,8 @@ tests/cases/conformance/types/union/unionTypeMembers.ts(54,3): error TS2339: Pro x.commonMethodDifferentParameterType; // No error - property exists x.commonMethodDifferentParameterType(strOrNum); // error - no call signatures because the type of this property is ((a: string) => string) | (a: number) => number ~~~~~~~~ -!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string & number'. -!!! error TS2345: Type 'string' is not assignable to type 'string & number'. -!!! error TS2345: Type 'string' is not assignable to type 'number'. +!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'never'. +!!! error TS2345: Type 'string' is not assignable to type 'never'. // and the call signatures arent identical num = x.commonMethodWithTypeParameter(num); num = x.commonMethodWithOwnTypeParameter(num); diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index 93e2a8660f65e..c3d5f891fb0d8 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -35,7 +35,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(180,5): error TS2322: Type type T00 = unknown & null; // null type T01 = unknown & undefined; // undefined - type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) + type T02 = unknown & null & undefined; // never type T03 = unknown & string; // string type T04 = unknown & string[]; // string[] type T05 = unknown & unknown; // unknown diff --git a/tests/baselines/reference/unknownType1.js b/tests/baselines/reference/unknownType1.js index a5183fd50294c..688fbf8f93c01 100644 --- a/tests/baselines/reference/unknownType1.js +++ b/tests/baselines/reference/unknownType1.js @@ -3,7 +3,7 @@ type T00 = unknown & null; // null type T01 = unknown & undefined; // undefined -type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) +type T02 = unknown & null & undefined; // never type T03 = unknown & string; // string type T04 = unknown & string[]; // string[] type T05 = unknown & unknown; // unknown diff --git a/tests/baselines/reference/unknownType1.symbols b/tests/baselines/reference/unknownType1.symbols index d4bdffc0163c8..95a3587baabd8 100644 --- a/tests/baselines/reference/unknownType1.symbols +++ b/tests/baselines/reference/unknownType1.symbols @@ -7,7 +7,7 @@ type T00 = unknown & null; // null type T01 = unknown & undefined; // undefined >T01 : Symbol(T01, Decl(unknownType1.ts, 2, 26)) -type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) +type T02 = unknown & null & undefined; // never >T02 : Symbol(T02, Decl(unknownType1.ts, 3, 31)) type T03 = unknown & string; // string diff --git a/tests/baselines/reference/unknownType1.types b/tests/baselines/reference/unknownType1.types index a464864d0d19d..7d28468169846 100644 --- a/tests/baselines/reference/unknownType1.types +++ b/tests/baselines/reference/unknownType1.types @@ -8,8 +8,8 @@ type T00 = unknown & null; // null type T01 = unknown & undefined; // undefined >T01 : undefined -type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) ->T02 : T02 +type T02 = unknown & null & undefined; // never +>T02 : never >null : null type T03 = unknown & string; // string From d2397e0380876bc3eeb4cdaaefebe7b87e93b640 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 9 Jun 2019 10:05:55 -0700 Subject: [PATCH 4/7] Fix minor issue --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 856e6bcd5d43b..3bf8810a84482 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9889,7 +9889,7 @@ namespace ts { // a void-like type and a type known to be non-void-like, or // a non-primitive type and a type known to be primitive. if (includes & TypeFlags.Never || - includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || + strictNullChecks && includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || includes & TypeFlags.NonPrimitive && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) || includes & TypeFlags.StringLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) || includes & TypeFlags.NumberLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) || From aa0ea5116999a4c67ad7d1427d68e8e4da61be5b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 9 Jun 2019 10:11:36 -0700 Subject: [PATCH 5/7] Update fourslash tests --- tests/cases/fourslash/tsxQuickInfo6.ts | 2 +- tests/cases/fourslash/tsxQuickInfo7.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cases/fourslash/tsxQuickInfo6.ts b/tests/cases/fourslash/tsxQuickInfo6.ts index b00216b864e56..e9736b96bc73f 100644 --- a/tests/cases/fourslash/tsxQuickInfo6.ts +++ b/tests/cases/fourslash/tsxQuickInfo6.ts @@ -15,5 +15,5 @@ verify.quickInfos({ 1: "function ComponentSpecific(l: {\n prop: number;\n}): any", - 2: "function ComponentSpecific(l: {\n prop: number & string;\n}): any" + 2: "function ComponentSpecific(l: {\n prop: never;\n}): any" }); diff --git a/tests/cases/fourslash/tsxQuickInfo7.ts b/tests/cases/fourslash/tsxQuickInfo7.ts index 8b3493dd8d4e5..c434276621adb 100644 --- a/tests/cases/fourslash/tsxQuickInfo7.ts +++ b/tests/cases/fourslash/tsxQuickInfo7.ts @@ -24,6 +24,6 @@ verify.quickInfos({ 3: "function OverloadComponent(attr: {\n b: string;\n a: boolean;\n}): any (+2 overloads)", 4: "function OverloadComponent(): any (+2 overloads)", // Subtype pass chooses this overload, since `a` is missing from the top overload, and `ignore-prop` is missing from the second (while T & {ignore-prop: true} is a proper subtype of `{}`) 5: "function OverloadComponent(): any (+2 overloads)", - 6: "function OverloadComponent(attr: {\n b: string & number;\n a: boolean;\n}): any (+2 overloads)", - 7: "function OverloadComponent(attr: {\n b: number & string;\n a: boolean;\n}): any (+2 overloads)", + 6: "function OverloadComponent(attr: {\n b: never;\n a: boolean;\n}): any (+2 overloads)", + 7: "function OverloadComponent(attr: {\n b: never;\n a: boolean;\n}): any (+2 overloads)", }); From 98bbb22bc4fb623dc5d8aaaf43b8e18d213f18c3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 9 Jun 2019 10:18:36 -0700 Subject: [PATCH 6/7] Add tests --- .../intersection/intersectionReduction.ts | 45 +++++++++++++- .../intersectionReductionStrict.ts | 58 +++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tests/cases/conformance/types/intersection/intersectionReductionStrict.ts diff --git a/tests/cases/conformance/types/intersection/intersectionReduction.ts b/tests/cases/conformance/types/intersection/intersectionReduction.ts index a6d2bf556b345..128f6fd067ab7 100644 --- a/tests/cases/conformance/types/intersection/intersectionReduction.ts +++ b/tests/cases/conformance/types/intersection/intersectionReduction.ts @@ -1,4 +1,4 @@ -// @strict +// @strict: false declare const sym1: unique symbol; declare const sym2: unique symbol; @@ -13,3 +13,46 @@ type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never type T10 = string & ('a' | 'b'); // 'a' | 'b' type T11 = (string | number) & ('a' | 10); // 'a' | 10 + +type N1 = 'a' & 'b'; +type N2 = { a: string } & null; +type N3 = { a: string } & undefined; +type N4 = string & number; +type N5 = number & object; +type N6 = symbol & string; +type N7 = void & string; + +type X = { x: string }; + +type X1 = X | 'a' & 'b'; +type X2 = X | { a: string } & null; +type X3 = X | { a: string } & undefined; +type X4 = X | string & number; +type X5 = X | number & object; +type X6 = X | symbol & string; +type X7 = X | void & string; + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +const x2 = { a: 'foo', b: true }; + +declare let k: 'a' | 'b'; + +x1[k] = 'bar' as any; // Error +x2[k] = 'bar' as any; // Error + +const enum Tag1 {} +const enum Tag2 {} + +declare let s1: string & Tag1; +declare let s2: string & Tag2; + +declare let t1: string & Tag1 | undefined; +declare let t2: string & Tag2 | undefined; + +s1 = s2; +s2 = s1; + +t1 = t2; +t2 = t1; diff --git a/tests/cases/conformance/types/intersection/intersectionReductionStrict.ts b/tests/cases/conformance/types/intersection/intersectionReductionStrict.ts new file mode 100644 index 0000000000000..2136f99db9ff9 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionReductionStrict.ts @@ -0,0 +1,58 @@ +// @strict: true + +declare const sym1: unique symbol; +declare const sym2: unique symbol; + +type T1 = string & 'a'; // 'a' +type T2 = 'a' & string & 'b'; // never +type T3 = number & 10; // 10 +type T4 = 10 & number & 20; // never +type T5 = symbol & typeof sym1; // typeof sym1 +type T6 = typeof sym1 & symbol & typeof sym2; // never +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +type T11 = (string | number) & ('a' | 10); // 'a' | 10 + +type N1 = 'a' & 'b'; +type N2 = { a: string } & null; +type N3 = { a: string } & undefined; +type N4 = string & number; +type N5 = number & object; +type N6 = symbol & string; +type N7 = void & string; + +type X = { x: string }; + +type X1 = X | 'a' & 'b'; +type X2 = X | { a: string } & null; +type X3 = X | { a: string } & undefined; +type X4 = X | string & number; +type X5 = X | number & object; +type X6 = X | symbol & string; +type X7 = X | void & string; + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +const x2 = { a: 'foo', b: true }; + +declare let k: 'a' | 'b'; + +x1[k] = 'bar' as any; // Error +x2[k] = 'bar' as any; // Error + +const enum Tag1 {} +const enum Tag2 {} + +declare let s1: string & Tag1; +declare let s2: string & Tag2; + +declare let t1: string & Tag1 | undefined; +declare let t2: string & Tag2 | undefined; + +s1 = s2; +s2 = s1; + +t1 = t2; +t2 = t1; From 015f4c5bc13b17889083263a3955532e9820f81b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 9 Jun 2019 10:18:47 -0700 Subject: [PATCH 7/7] Accept new baselines --- .../intersectionReduction.errors.txt | 66 +++++++ .../reference/intersectionReduction.js | 55 +++++- .../reference/intersectionReduction.symbols | 150 ++++++++++++++-- .../reference/intersectionReduction.types | 129 +++++++++++++- .../intersectionReductionStrict.errors.txt | 66 +++++++ .../reference/intersectionReductionStrict.js | 70 ++++++++ .../intersectionReductionStrict.symbols | 156 +++++++++++++++++ .../intersectionReductionStrict.types | 165 ++++++++++++++++++ 8 files changed, 835 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/intersectionReduction.errors.txt create mode 100644 tests/baselines/reference/intersectionReductionStrict.errors.txt create mode 100644 tests/baselines/reference/intersectionReductionStrict.js create mode 100644 tests/baselines/reference/intersectionReductionStrict.symbols create mode 100644 tests/baselines/reference/intersectionReductionStrict.types diff --git a/tests/baselines/reference/intersectionReduction.errors.txt b/tests/baselines/reference/intersectionReduction.errors.txt new file mode 100644 index 0000000000000..62631cca76b3c --- /dev/null +++ b/tests/baselines/reference/intersectionReduction.errors.txt @@ -0,0 +1,66 @@ +tests/cases/conformance/types/intersection/intersectionReduction.ts(40,1): error TS2322: Type 'any' is not assignable to type 'never'. +tests/cases/conformance/types/intersection/intersectionReduction.ts(41,1): error TS2322: Type 'any' is not assignable to type 'never'. + + +==== tests/cases/conformance/types/intersection/intersectionReduction.ts (2 errors) ==== + declare const sym1: unique symbol; + declare const sym2: unique symbol; + + type T1 = string & 'a'; // 'a' + type T2 = 'a' & string & 'b'; // never + type T3 = number & 10; // 10 + type T4 = 10 & number & 20; // never + type T5 = symbol & typeof sym1; // typeof sym1 + type T6 = typeof sym1 & symbol & typeof sym2; // never + type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never + + type T10 = string & ('a' | 'b'); // 'a' | 'b' + type T11 = (string | number) & ('a' | 10); // 'a' | 10 + + type N1 = 'a' & 'b'; + type N2 = { a: string } & null; + type N3 = { a: string } & undefined; + type N4 = string & number; + type N5 = number & object; + type N6 = symbol & string; + type N7 = void & string; + + type X = { x: string }; + + type X1 = X | 'a' & 'b'; + type X2 = X | { a: string } & null; + type X3 = X | { a: string } & undefined; + type X4 = X | string & number; + type X5 = X | number & object; + type X6 = X | symbol & string; + type X7 = X | void & string; + + // Repro from #31663 + + const x1 = { a: 'foo', b: 42 }; + const x2 = { a: 'foo', b: true }; + + declare let k: 'a' | 'b'; + + x1[k] = 'bar' as any; // Error + ~~~~~ +!!! error TS2322: Type 'any' is not assignable to type 'never'. + x2[k] = 'bar' as any; // Error + ~~~~~ +!!! error TS2322: Type 'any' is not assignable to type 'never'. + + const enum Tag1 {} + const enum Tag2 {} + + declare let s1: string & Tag1; + declare let s2: string & Tag2; + + declare let t1: string & Tag1 | undefined; + declare let t2: string & Tag2 | undefined; + + s1 = s2; + s2 = s1; + + t1 = t2; + t2 = t1; + \ No newline at end of file diff --git a/tests/baselines/reference/intersectionReduction.js b/tests/baselines/reference/intersectionReduction.js index ba0c3cea77564..f2009cd9cc7e8 100644 --- a/tests/baselines/reference/intersectionReduction.js +++ b/tests/baselines/reference/intersectionReduction.js @@ -1,6 +1,4 @@ //// [intersectionReduction.ts] -// @strict - declare const sym1: unique symbol; declare const sym2: unique symbol; @@ -14,7 +12,58 @@ type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never type T10 = string & ('a' | 'b'); // 'a' | 'b' type T11 = (string | number) & ('a' | 10); // 'a' | 10 + +type N1 = 'a' & 'b'; +type N2 = { a: string } & null; +type N3 = { a: string } & undefined; +type N4 = string & number; +type N5 = number & object; +type N6 = symbol & string; +type N7 = void & string; + +type X = { x: string }; + +type X1 = X | 'a' & 'b'; +type X2 = X | { a: string } & null; +type X3 = X | { a: string } & undefined; +type X4 = X | string & number; +type X5 = X | number & object; +type X6 = X | symbol & string; +type X7 = X | void & string; + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +const x2 = { a: 'foo', b: true }; + +declare let k: 'a' | 'b'; + +x1[k] = 'bar' as any; // Error +x2[k] = 'bar' as any; // Error + +const enum Tag1 {} +const enum Tag2 {} + +declare let s1: string & Tag1; +declare let s2: string & Tag2; + +declare let t1: string & Tag1 | undefined; +declare let t2: string & Tag2 | undefined; + +s1 = s2; +s2 = s1; + +t1 = t2; +t2 = t1; //// [intersectionReduction.js] -// @strict +// Repro from #31663 +var x1 = { a: 'foo', b: 42 }; +var x2 = { a: 'foo', b: true }; +x1[k] = 'bar'; // Error +x2[k] = 'bar'; // Error +s1 = s2; +s2 = s1; +t1 = t2; +t2 = t1; diff --git a/tests/baselines/reference/intersectionReduction.symbols b/tests/baselines/reference/intersectionReduction.symbols index e932e3eb6c680..3e22d2e26965f 100644 --- a/tests/baselines/reference/intersectionReduction.symbols +++ b/tests/baselines/reference/intersectionReduction.symbols @@ -1,40 +1,156 @@ === tests/cases/conformance/types/intersection/intersectionReduction.ts === -// @strict - declare const sym1: unique symbol; ->sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13)) declare const sym2: unique symbol; ->sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13)) +>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 1, 13)) type T1 = string & 'a'; // 'a' ->T1 : Symbol(T1, Decl(intersectionReduction.ts, 3, 34)) +>T1 : Symbol(T1, Decl(intersectionReduction.ts, 1, 34)) type T2 = 'a' & string & 'b'; // never ->T2 : Symbol(T2, Decl(intersectionReduction.ts, 5, 23)) +>T2 : Symbol(T2, Decl(intersectionReduction.ts, 3, 23)) type T3 = number & 10; // 10 ->T3 : Symbol(T3, Decl(intersectionReduction.ts, 6, 29)) +>T3 : Symbol(T3, Decl(intersectionReduction.ts, 4, 29)) type T4 = 10 & number & 20; // never ->T4 : Symbol(T4, Decl(intersectionReduction.ts, 7, 22)) +>T4 : Symbol(T4, Decl(intersectionReduction.ts, 5, 22)) type T5 = symbol & typeof sym1; // typeof sym1 ->T5 : Symbol(T5, Decl(intersectionReduction.ts, 8, 27)) ->sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) +>T5 : Symbol(T5, Decl(intersectionReduction.ts, 6, 27)) +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13)) type T6 = typeof sym1 & symbol & typeof sym2; // never ->T6 : Symbol(T6, Decl(intersectionReduction.ts, 9, 31)) ->sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) ->sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13)) +>T6 : Symbol(T6, Decl(intersectionReduction.ts, 7, 31)) +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13)) +>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 1, 13)) type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never ->T7 : Symbol(T7, Decl(intersectionReduction.ts, 10, 45)) ->sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) +>T7 : Symbol(T7, Decl(intersectionReduction.ts, 8, 45)) +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13)) type T10 = string & ('a' | 'b'); // 'a' | 'b' ->T10 : Symbol(T10, Decl(intersectionReduction.ts, 11, 60)) +>T10 : Symbol(T10, Decl(intersectionReduction.ts, 9, 60)) type T11 = (string | number) & ('a' | 10); // 'a' | 10 ->T11 : Symbol(T11, Decl(intersectionReduction.ts, 13, 32)) +>T11 : Symbol(T11, Decl(intersectionReduction.ts, 11, 32)) + +type N1 = 'a' & 'b'; +>N1 : Symbol(N1, Decl(intersectionReduction.ts, 12, 42)) + +type N2 = { a: string } & null; +>N2 : Symbol(N2, Decl(intersectionReduction.ts, 14, 20)) +>a : Symbol(a, Decl(intersectionReduction.ts, 15, 11)) + +type N3 = { a: string } & undefined; +>N3 : Symbol(N3, Decl(intersectionReduction.ts, 15, 31)) +>a : Symbol(a, Decl(intersectionReduction.ts, 16, 11)) + +type N4 = string & number; +>N4 : Symbol(N4, Decl(intersectionReduction.ts, 16, 36)) + +type N5 = number & object; +>N5 : Symbol(N5, Decl(intersectionReduction.ts, 17, 26)) + +type N6 = symbol & string; +>N6 : Symbol(N6, Decl(intersectionReduction.ts, 18, 26)) + +type N7 = void & string; +>N7 : Symbol(N7, Decl(intersectionReduction.ts, 19, 26)) + +type X = { x: string }; +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) +>x : Symbol(x, Decl(intersectionReduction.ts, 22, 10)) + +type X1 = X | 'a' & 'b'; +>X1 : Symbol(X1, Decl(intersectionReduction.ts, 22, 23)) +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) + +type X2 = X | { a: string } & null; +>X2 : Symbol(X2, Decl(intersectionReduction.ts, 24, 24)) +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) +>a : Symbol(a, Decl(intersectionReduction.ts, 25, 15)) + +type X3 = X | { a: string } & undefined; +>X3 : Symbol(X3, Decl(intersectionReduction.ts, 25, 35)) +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) +>a : Symbol(a, Decl(intersectionReduction.ts, 26, 15)) + +type X4 = X | string & number; +>X4 : Symbol(X4, Decl(intersectionReduction.ts, 26, 40)) +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) + +type X5 = X | number & object; +>X5 : Symbol(X5, Decl(intersectionReduction.ts, 27, 30)) +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) + +type X6 = X | symbol & string; +>X6 : Symbol(X6, Decl(intersectionReduction.ts, 28, 30)) +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) + +type X7 = X | void & string; +>X7 : Symbol(X7, Decl(intersectionReduction.ts, 29, 30)) +>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24)) + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +>x1 : Symbol(x1, Decl(intersectionReduction.ts, 34, 5)) +>a : Symbol(a, Decl(intersectionReduction.ts, 34, 12)) +>b : Symbol(b, Decl(intersectionReduction.ts, 34, 22)) + +const x2 = { a: 'foo', b: true }; +>x2 : Symbol(x2, Decl(intersectionReduction.ts, 35, 5)) +>a : Symbol(a, Decl(intersectionReduction.ts, 35, 12)) +>b : Symbol(b, Decl(intersectionReduction.ts, 35, 22)) + +declare let k: 'a' | 'b'; +>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11)) + +x1[k] = 'bar' as any; // Error +>x1 : Symbol(x1, Decl(intersectionReduction.ts, 34, 5)) +>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11)) + +x2[k] = 'bar' as any; // Error +>x2 : Symbol(x2, Decl(intersectionReduction.ts, 35, 5)) +>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11)) + +const enum Tag1 {} +>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21)) + +const enum Tag2 {} +>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18)) + +declare let s1: string & Tag1; +>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11)) +>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21)) + +declare let s2: string & Tag2; +>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11)) +>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18)) + +declare let t1: string & Tag1 | undefined; +>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11)) +>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21)) + +declare let t2: string & Tag2 | undefined; +>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11)) +>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18)) + +s1 = s2; +>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11)) +>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11)) + +s2 = s1; +>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11)) +>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11)) + +t1 = t2; +>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11)) +>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11)) + +t2 = t1; +>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11)) +>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11)) diff --git a/tests/baselines/reference/intersectionReduction.types b/tests/baselines/reference/intersectionReduction.types index 725e1b5629ea3..9dfeea5c0e508 100644 --- a/tests/baselines/reference/intersectionReduction.types +++ b/tests/baselines/reference/intersectionReduction.types @@ -1,6 +1,4 @@ === tests/cases/conformance/types/intersection/intersectionReduction.ts === -// @strict - declare const sym1: unique symbol; >sym1 : unique symbol @@ -38,3 +36,130 @@ type T10 = string & ('a' | 'b'); // 'a' | 'b' type T11 = (string | number) & ('a' | 10); // 'a' | 10 >T11 : "a" | 10 +type N1 = 'a' & 'b'; +>N1 : never + +type N2 = { a: string } & null; +>N2 : null +>a : string +>null : null + +type N3 = { a: string } & undefined; +>N3 : undefined +>a : string + +type N4 = string & number; +>N4 : never + +type N5 = number & object; +>N5 : never + +type N6 = symbol & string; +>N6 : never + +type N7 = void & string; +>N7 : never + +type X = { x: string }; +>X : X +>x : string + +type X1 = X | 'a' & 'b'; +>X1 : X + +type X2 = X | { a: string } & null; +>X2 : X +>a : string +>null : null + +type X3 = X | { a: string } & undefined; +>X3 : X +>a : string + +type X4 = X | string & number; +>X4 : X + +type X5 = X | number & object; +>X5 : X + +type X6 = X | symbol & string; +>X6 : X + +type X7 = X | void & string; +>X7 : X + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +>x1 : { a: string; b: number; } +>{ a: 'foo', b: 42 } : { a: string; b: number; } +>a : string +>'foo' : "foo" +>b : number +>42 : 42 + +const x2 = { a: 'foo', b: true }; +>x2 : { a: string; b: boolean; } +>{ a: 'foo', b: true } : { a: string; b: boolean; } +>a : string +>'foo' : "foo" +>b : boolean +>true : true + +declare let k: 'a' | 'b'; +>k : "a" | "b" + +x1[k] = 'bar' as any; // Error +>x1[k] = 'bar' as any : any +>x1[k] : never +>x1 : { a: string; b: number; } +>k : "a" | "b" +>'bar' as any : any +>'bar' : "bar" + +x2[k] = 'bar' as any; // Error +>x2[k] = 'bar' as any : any +>x2[k] : never +>x2 : { a: string; b: boolean; } +>k : "a" | "b" +>'bar' as any : any +>'bar' : "bar" + +const enum Tag1 {} +>Tag1 : Tag1 + +const enum Tag2 {} +>Tag2 : Tag2 + +declare let s1: string & Tag1; +>s1 : never + +declare let s2: string & Tag2; +>s2 : never + +declare let t1: string & Tag1 | undefined; +>t1 : undefined + +declare let t2: string & Tag2 | undefined; +>t2 : undefined + +s1 = s2; +>s1 = s2 : never +>s1 : never +>s2 : never + +s2 = s1; +>s2 = s1 : never +>s2 : never +>s1 : never + +t1 = t2; +>t1 = t2 : undefined +>t1 : undefined +>t2 : undefined + +t2 = t1; +>t2 = t1 : undefined +>t2 : undefined +>t1 : undefined + diff --git a/tests/baselines/reference/intersectionReductionStrict.errors.txt b/tests/baselines/reference/intersectionReductionStrict.errors.txt new file mode 100644 index 0000000000000..bf174ce04ef60 --- /dev/null +++ b/tests/baselines/reference/intersectionReductionStrict.errors.txt @@ -0,0 +1,66 @@ +tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(40,1): error TS2322: Type 'any' is not assignable to type 'never'. +tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(41,1): error TS2322: Type 'any' is not assignable to type 'never'. + + +==== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts (2 errors) ==== + declare const sym1: unique symbol; + declare const sym2: unique symbol; + + type T1 = string & 'a'; // 'a' + type T2 = 'a' & string & 'b'; // never + type T3 = number & 10; // 10 + type T4 = 10 & number & 20; // never + type T5 = symbol & typeof sym1; // typeof sym1 + type T6 = typeof sym1 & symbol & typeof sym2; // never + type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never + + type T10 = string & ('a' | 'b'); // 'a' | 'b' + type T11 = (string | number) & ('a' | 10); // 'a' | 10 + + type N1 = 'a' & 'b'; + type N2 = { a: string } & null; + type N3 = { a: string } & undefined; + type N4 = string & number; + type N5 = number & object; + type N6 = symbol & string; + type N7 = void & string; + + type X = { x: string }; + + type X1 = X | 'a' & 'b'; + type X2 = X | { a: string } & null; + type X3 = X | { a: string } & undefined; + type X4 = X | string & number; + type X5 = X | number & object; + type X6 = X | symbol & string; + type X7 = X | void & string; + + // Repro from #31663 + + const x1 = { a: 'foo', b: 42 }; + const x2 = { a: 'foo', b: true }; + + declare let k: 'a' | 'b'; + + x1[k] = 'bar' as any; // Error + ~~~~~ +!!! error TS2322: Type 'any' is not assignable to type 'never'. + x2[k] = 'bar' as any; // Error + ~~~~~ +!!! error TS2322: Type 'any' is not assignable to type 'never'. + + const enum Tag1 {} + const enum Tag2 {} + + declare let s1: string & Tag1; + declare let s2: string & Tag2; + + declare let t1: string & Tag1 | undefined; + declare let t2: string & Tag2 | undefined; + + s1 = s2; + s2 = s1; + + t1 = t2; + t2 = t1; + \ No newline at end of file diff --git a/tests/baselines/reference/intersectionReductionStrict.js b/tests/baselines/reference/intersectionReductionStrict.js new file mode 100644 index 0000000000000..32845471a06a2 --- /dev/null +++ b/tests/baselines/reference/intersectionReductionStrict.js @@ -0,0 +1,70 @@ +//// [intersectionReductionStrict.ts] +declare const sym1: unique symbol; +declare const sym2: unique symbol; + +type T1 = string & 'a'; // 'a' +type T2 = 'a' & string & 'b'; // never +type T3 = number & 10; // 10 +type T4 = 10 & number & 20; // never +type T5 = symbol & typeof sym1; // typeof sym1 +type T6 = typeof sym1 & symbol & typeof sym2; // never +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +type T11 = (string | number) & ('a' | 10); // 'a' | 10 + +type N1 = 'a' & 'b'; +type N2 = { a: string } & null; +type N3 = { a: string } & undefined; +type N4 = string & number; +type N5 = number & object; +type N6 = symbol & string; +type N7 = void & string; + +type X = { x: string }; + +type X1 = X | 'a' & 'b'; +type X2 = X | { a: string } & null; +type X3 = X | { a: string } & undefined; +type X4 = X | string & number; +type X5 = X | number & object; +type X6 = X | symbol & string; +type X7 = X | void & string; + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +const x2 = { a: 'foo', b: true }; + +declare let k: 'a' | 'b'; + +x1[k] = 'bar' as any; // Error +x2[k] = 'bar' as any; // Error + +const enum Tag1 {} +const enum Tag2 {} + +declare let s1: string & Tag1; +declare let s2: string & Tag2; + +declare let t1: string & Tag1 | undefined; +declare let t2: string & Tag2 | undefined; + +s1 = s2; +s2 = s1; + +t1 = t2; +t2 = t1; + + +//// [intersectionReductionStrict.js] +"use strict"; +// Repro from #31663 +var x1 = { a: 'foo', b: 42 }; +var x2 = { a: 'foo', b: true }; +x1[k] = 'bar'; // Error +x2[k] = 'bar'; // Error +s1 = s2; +s2 = s1; +t1 = t2; +t2 = t1; diff --git a/tests/baselines/reference/intersectionReductionStrict.symbols b/tests/baselines/reference/intersectionReductionStrict.symbols new file mode 100644 index 0000000000000..6e9d7e03a8e04 --- /dev/null +++ b/tests/baselines/reference/intersectionReductionStrict.symbols @@ -0,0 +1,156 @@ +=== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts === +declare const sym1: unique symbol; +>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13)) + +declare const sym2: unique symbol; +>sym2 : Symbol(sym2, Decl(intersectionReductionStrict.ts, 1, 13)) + +type T1 = string & 'a'; // 'a' +>T1 : Symbol(T1, Decl(intersectionReductionStrict.ts, 1, 34)) + +type T2 = 'a' & string & 'b'; // never +>T2 : Symbol(T2, Decl(intersectionReductionStrict.ts, 3, 23)) + +type T3 = number & 10; // 10 +>T3 : Symbol(T3, Decl(intersectionReductionStrict.ts, 4, 29)) + +type T4 = 10 & number & 20; // never +>T4 : Symbol(T4, Decl(intersectionReductionStrict.ts, 5, 22)) + +type T5 = symbol & typeof sym1; // typeof sym1 +>T5 : Symbol(T5, Decl(intersectionReductionStrict.ts, 6, 27)) +>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13)) + +type T6 = typeof sym1 & symbol & typeof sym2; // never +>T6 : Symbol(T6, Decl(intersectionReductionStrict.ts, 7, 31)) +>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13)) +>sym2 : Symbol(sym2, Decl(intersectionReductionStrict.ts, 1, 13)) + +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never +>T7 : Symbol(T7, Decl(intersectionReductionStrict.ts, 8, 45)) +>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13)) + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +>T10 : Symbol(T10, Decl(intersectionReductionStrict.ts, 9, 60)) + +type T11 = (string | number) & ('a' | 10); // 'a' | 10 +>T11 : Symbol(T11, Decl(intersectionReductionStrict.ts, 11, 32)) + +type N1 = 'a' & 'b'; +>N1 : Symbol(N1, Decl(intersectionReductionStrict.ts, 12, 42)) + +type N2 = { a: string } & null; +>N2 : Symbol(N2, Decl(intersectionReductionStrict.ts, 14, 20)) +>a : Symbol(a, Decl(intersectionReductionStrict.ts, 15, 11)) + +type N3 = { a: string } & undefined; +>N3 : Symbol(N3, Decl(intersectionReductionStrict.ts, 15, 31)) +>a : Symbol(a, Decl(intersectionReductionStrict.ts, 16, 11)) + +type N4 = string & number; +>N4 : Symbol(N4, Decl(intersectionReductionStrict.ts, 16, 36)) + +type N5 = number & object; +>N5 : Symbol(N5, Decl(intersectionReductionStrict.ts, 17, 26)) + +type N6 = symbol & string; +>N6 : Symbol(N6, Decl(intersectionReductionStrict.ts, 18, 26)) + +type N7 = void & string; +>N7 : Symbol(N7, Decl(intersectionReductionStrict.ts, 19, 26)) + +type X = { x: string }; +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) +>x : Symbol(x, Decl(intersectionReductionStrict.ts, 22, 10)) + +type X1 = X | 'a' & 'b'; +>X1 : Symbol(X1, Decl(intersectionReductionStrict.ts, 22, 23)) +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) + +type X2 = X | { a: string } & null; +>X2 : Symbol(X2, Decl(intersectionReductionStrict.ts, 24, 24)) +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) +>a : Symbol(a, Decl(intersectionReductionStrict.ts, 25, 15)) + +type X3 = X | { a: string } & undefined; +>X3 : Symbol(X3, Decl(intersectionReductionStrict.ts, 25, 35)) +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) +>a : Symbol(a, Decl(intersectionReductionStrict.ts, 26, 15)) + +type X4 = X | string & number; +>X4 : Symbol(X4, Decl(intersectionReductionStrict.ts, 26, 40)) +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) + +type X5 = X | number & object; +>X5 : Symbol(X5, Decl(intersectionReductionStrict.ts, 27, 30)) +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) + +type X6 = X | symbol & string; +>X6 : Symbol(X6, Decl(intersectionReductionStrict.ts, 28, 30)) +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) + +type X7 = X | void & string; +>X7 : Symbol(X7, Decl(intersectionReductionStrict.ts, 29, 30)) +>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24)) + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 34, 5)) +>a : Symbol(a, Decl(intersectionReductionStrict.ts, 34, 12)) +>b : Symbol(b, Decl(intersectionReductionStrict.ts, 34, 22)) + +const x2 = { a: 'foo', b: true }; +>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 35, 5)) +>a : Symbol(a, Decl(intersectionReductionStrict.ts, 35, 12)) +>b : Symbol(b, Decl(intersectionReductionStrict.ts, 35, 22)) + +declare let k: 'a' | 'b'; +>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11)) + +x1[k] = 'bar' as any; // Error +>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 34, 5)) +>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11)) + +x2[k] = 'bar' as any; // Error +>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 35, 5)) +>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11)) + +const enum Tag1 {} +>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21)) + +const enum Tag2 {} +>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18)) + +declare let s1: string & Tag1; +>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11)) +>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21)) + +declare let s2: string & Tag2; +>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11)) +>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18)) + +declare let t1: string & Tag1 | undefined; +>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11)) +>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21)) + +declare let t2: string & Tag2 | undefined; +>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11)) +>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18)) + +s1 = s2; +>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11)) +>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11)) + +s2 = s1; +>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11)) +>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11)) + +t1 = t2; +>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11)) +>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11)) + +t2 = t1; +>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11)) +>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11)) + diff --git a/tests/baselines/reference/intersectionReductionStrict.types b/tests/baselines/reference/intersectionReductionStrict.types new file mode 100644 index 0000000000000..8227f6b407259 --- /dev/null +++ b/tests/baselines/reference/intersectionReductionStrict.types @@ -0,0 +1,165 @@ +=== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts === +declare const sym1: unique symbol; +>sym1 : unique symbol + +declare const sym2: unique symbol; +>sym2 : unique symbol + +type T1 = string & 'a'; // 'a' +>T1 : "a" + +type T2 = 'a' & string & 'b'; // never +>T2 : never + +type T3 = number & 10; // 10 +>T3 : 10 + +type T4 = 10 & number & 20; // never +>T4 : never + +type T5 = symbol & typeof sym1; // typeof sym1 +>T5 : unique symbol +>sym1 : unique symbol + +type T6 = typeof sym1 & symbol & typeof sym2; // never +>T6 : never +>sym1 : unique symbol +>sym2 : unique symbol + +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never +>T7 : never +>sym1 : unique symbol + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +>T10 : "a" | "b" + +type T11 = (string | number) & ('a' | 10); // 'a' | 10 +>T11 : "a" | 10 + +type N1 = 'a' & 'b'; +>N1 : never + +type N2 = { a: string } & null; +>N2 : never +>a : string +>null : null + +type N3 = { a: string } & undefined; +>N3 : never +>a : string + +type N4 = string & number; +>N4 : never + +type N5 = number & object; +>N5 : never + +type N6 = symbol & string; +>N6 : never + +type N7 = void & string; +>N7 : never + +type X = { x: string }; +>X : X +>x : string + +type X1 = X | 'a' & 'b'; +>X1 : X + +type X2 = X | { a: string } & null; +>X2 : X +>a : string +>null : null + +type X3 = X | { a: string } & undefined; +>X3 : X +>a : string + +type X4 = X | string & number; +>X4 : X + +type X5 = X | number & object; +>X5 : X + +type X6 = X | symbol & string; +>X6 : X + +type X7 = X | void & string; +>X7 : X + +// Repro from #31663 + +const x1 = { a: 'foo', b: 42 }; +>x1 : { a: string; b: number; } +>{ a: 'foo', b: 42 } : { a: string; b: number; } +>a : string +>'foo' : "foo" +>b : number +>42 : 42 + +const x2 = { a: 'foo', b: true }; +>x2 : { a: string; b: boolean; } +>{ a: 'foo', b: true } : { a: string; b: boolean; } +>a : string +>'foo' : "foo" +>b : boolean +>true : true + +declare let k: 'a' | 'b'; +>k : "a" | "b" + +x1[k] = 'bar' as any; // Error +>x1[k] = 'bar' as any : any +>x1[k] : never +>x1 : { a: string; b: number; } +>k : "a" | "b" +>'bar' as any : any +>'bar' : "bar" + +x2[k] = 'bar' as any; // Error +>x2[k] = 'bar' as any : any +>x2[k] : never +>x2 : { a: string; b: boolean; } +>k : "a" | "b" +>'bar' as any : any +>'bar' : "bar" + +const enum Tag1 {} +>Tag1 : Tag1 + +const enum Tag2 {} +>Tag2 : Tag2 + +declare let s1: string & Tag1; +>s1 : never + +declare let s2: string & Tag2; +>s2 : never + +declare let t1: string & Tag1 | undefined; +>t1 : undefined + +declare let t2: string & Tag2 | undefined; +>t2 : undefined + +s1 = s2; +>s1 = s2 : never +>s1 : never +>s2 : never + +s2 = s1; +>s2 = s1 : never +>s2 : never +>s1 : never + +t1 = t2; +>t1 = t2 : undefined +>t1 : undefined +>t2 : undefined + +t2 = t1; +>t2 = t1 : undefined +>t2 : undefined +>t1 : undefined +