diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 59bbab5eb5e31..cca0e55ddaf7b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4102,7 +4102,9 @@ namespace ts { return undefined!; // TODO: GH#18217 } - type = getReducedType(type); + if (!(context.flags & NodeBuilderFlags.PreserveVacuousIntersections)) { + type = getReducedType(type); + } if (type.flags & TypeFlags.Any) { context.approximateLength += 3; @@ -15528,6 +15530,10 @@ namespace ts { return result; } } + else if (getObjectFlags(originalTarget) & ObjectFlags.IsNeverIntersection) { + const intersectionString = typeToString(originalTarget, /*enclosingDeclaration*/ undefined, TypeFormatFlags.PreserveVacuousIntersections); + errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.The_type_never_was_reduced_from_the_intersection_0_Each_type_of_that_intersection_has_properties_that_conflict_so_values_of_that_type_can_never_exist, intersectionString); + } if (!headMessage && maybeSuppress) { lastSkippedInfo = [source, target]; // Used by, eg, missing property checking to replace the top-level message with a more informative one @@ -24098,6 +24104,10 @@ namespace ts { relatedInfo = suggestion.valueDeclaration && createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestedName); } else { + if (getObjectFlags(containingType) & ObjectFlags.IsNeverIntersection) { + const intersectionString = typeToString(containingType, /*enclosingDeclaration*/ undefined, TypeFormatFlags.PreserveVacuousIntersections); + errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.The_type_never_was_reduced_from_the_intersection_0_Each_type_of_that_intersection_has_properties_that_conflict_so_values_of_that_type_can_never_exist, intersectionString); + } errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType)); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d0d7b1f778555..152c736d07fb3 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5653,5 +5653,9 @@ "An optional chain cannot contain private identifiers.": { "category": "Error", "code": 18030 + }, + "The type 'never' was reduced from the intersection '{0}'. Each type of that intersection has properties that conflict, so values of that type can never exist.": { + "category": "Error", + "code": 18031 } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8b6f5f8fa5af6..873863585ddeb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3687,6 +3687,7 @@ namespace ts { OmitParameterModifiers = 1 << 13, // Omit modifiers on parameters UseAliasDefinedOutsideCurrentScope = 1 << 14, // Allow non-visible aliases UseSingleQuotesForStringLiteralType = 1 << 28, // Use single quotes for string literal type + PreserveVacuousIntersections = 1 << 29, // uh oh... // Error handling AllowThisInObjectLiteral = 1 << 15, @@ -3730,6 +3731,7 @@ namespace ts { UseAliasDefinedOutsideCurrentScope = 1 << 14, // For a `type T = ... ` defined in a different file, write `T` instead of its value, even though `T` can't be accessed in the current scope. UseSingleQuotesForStringLiteralType = 1 << 28, // Use single quotes for string literal type + PreserveVacuousIntersections = 1 << 29, // uh oh // Error Handling AllowUniqueESSymbolType = 1 << 20, // This is bit 20 to align with the same bit in `NodeBuilderFlags` @@ -3749,7 +3751,7 @@ namespace ts { NodeBuilderFlagsMask = NoTruncation | WriteArrayAsGenericType | UseStructuralFallback | WriteTypeArgumentsOfSignature | UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias | - UseSingleQuotesForStringLiteralType, + UseSingleQuotesForStringLiteralType | PreserveVacuousIntersections, } export const enum SymbolFormatFlags { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3744fa68605c8..0ef7b63118bd3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2136,6 +2136,7 @@ declare namespace ts { OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, UseSingleQuotesForStringLiteralType = 268435456, + PreserveVacuousIntersections = 536870912, AllowThisInObjectLiteral = 32768, AllowQualifedNameInPlaceOfIdentifier = 65536, AllowAnonymousIdentifier = 131072, @@ -2164,6 +2165,7 @@ declare namespace ts { OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, UseSingleQuotesForStringLiteralType = 268435456, + PreserveVacuousIntersections = 536870912, AllowUniqueESSymbolType = 1048576, AddUndefined = 131072, WriteArrowStyleSignature = 262144, @@ -2172,7 +2174,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 277904747 + NodeBuilderFlagsMask = 814775659 } export enum SymbolFormatFlags { None = 0, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 1e606168e0f71..9173d4e3c46cb 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2136,6 +2136,7 @@ declare namespace ts { OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, UseSingleQuotesForStringLiteralType = 268435456, + PreserveVacuousIntersections = 536870912, AllowThisInObjectLiteral = 32768, AllowQualifedNameInPlaceOfIdentifier = 65536, AllowAnonymousIdentifier = 131072, @@ -2164,6 +2165,7 @@ declare namespace ts { OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, UseSingleQuotesForStringLiteralType = 268435456, + PreserveVacuousIntersections = 536870912, AllowUniqueESSymbolType = 1048576, AddUndefined = 131072, WriteArrowStyleSignature = 262144, @@ -2172,7 +2174,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 277904747 + NodeBuilderFlagsMask = 814775659 } export enum SymbolFormatFlags { None = 0, diff --git a/tests/baselines/reference/intersectionReduction.errors.txt b/tests/baselines/reference/intersectionReduction.errors.txt index 7f979f3aeabe8..63e2b4f6a80f4 100644 --- a/tests/baselines/reference/intersectionReduction.errors.txt +++ b/tests/baselines/reference/intersectionReduction.errors.txt @@ -1,9 +1,12 @@ tests/cases/conformance/types/intersection/intersectionReduction.ts(38,4): error TS2339: Property 'kind' does not exist on type 'never'. -tests/cases/conformance/types/intersection/intersectionReduction.ts(80,1): error TS2322: Type 'any' is not assignable to type 'never'. + The type 'never' was reduced from the intersection 'A & B'. Each type of that intersection has properties that conflict, so values of that type can never exist. +tests/cases/conformance/types/intersection/intersectionReduction.ts(39,1): error TS2322: Type '42' is not assignable to type 'never'. + The type 'never' was reduced from the intersection 'A & B'. Each type of that intersection has properties that conflict, so values of that type can never exist. tests/cases/conformance/types/intersection/intersectionReduction.ts(81,1): error TS2322: Type 'any' is not assignable to type 'never'. +tests/cases/conformance/types/intersection/intersectionReduction.ts(82,1): error TS2322: Type 'any' is not assignable to type 'never'. -==== tests/cases/conformance/types/intersection/intersectionReduction.ts (3 errors) ==== +==== tests/cases/conformance/types/intersection/intersectionReduction.ts (4 errors) ==== declare const sym1: unique symbol; declare const sym2: unique symbol; @@ -44,6 +47,11 @@ tests/cases/conformance/types/intersection/intersectionReduction.ts(81,1): error ab.kind; // Error ~~~~ !!! error TS2339: Property 'kind' does not exist on type 'never'. +!!! error TS2339: The type 'never' was reduced from the intersection 'A & B'. Each type of that intersection has properties that conflict, so values of that type can never exist. + ab = 42; + ~~ +!!! error TS2322: Type '42' is not assignable to type 'never'. +!!! error TS2322: The type 'never' was reduced from the intersection 'A & B'. Each type of that intersection has properties that conflict, so values of that type can never exist. declare let x: A | (B & C); // A let a: A = x; diff --git a/tests/baselines/reference/intersectionReduction.js b/tests/baselines/reference/intersectionReduction.js index c04ce9973bcbe..37410a5a84f21 100644 --- a/tests/baselines/reference/intersectionReduction.js +++ b/tests/baselines/reference/intersectionReduction.js @@ -37,6 +37,7 @@ type C = { kind: 'c', foo: number }; declare let ab: A & B; ab.kind; // Error +ab = 42; declare let x: A | (B & C); // A let a: A = x; @@ -111,6 +112,7 @@ const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): //// [intersectionReduction.js] ab.kind; // Error +ab = 42; var a = x; var r1 = f10(a1); // unknown var r2 = f10(a2); // string diff --git a/tests/baselines/reference/intersectionReduction.symbols b/tests/baselines/reference/intersectionReduction.symbols index 2949e87b2c72a..1dca60a4a4621 100644 --- a/tests/baselines/reference/intersectionReduction.symbols +++ b/tests/baselines/reference/intersectionReduction.symbols @@ -116,84 +116,72 @@ declare let ab: A & B; ab.kind; // Error >ab : Symbol(ab, Decl(intersectionReduction.ts, 36, 11)) +ab = 42; +>ab : Symbol(ab, Decl(intersectionReduction.ts, 36, 11)) + declare let x: A | (B & C); // A ->x : Symbol(x, Decl(intersectionReduction.ts, 39, 11)) +>x : Symbol(x, Decl(intersectionReduction.ts, 40, 11)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) >C : Symbol(C, Decl(intersectionReduction.ts, 33, 36)) let a: A = x; ->a : Symbol(a, Decl(intersectionReduction.ts, 40, 3)) +>a : Symbol(a, Decl(intersectionReduction.ts, 41, 3)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) ->x : Symbol(x, Decl(intersectionReduction.ts, 39, 11)) +>x : Symbol(x, Decl(intersectionReduction.ts, 40, 11)) type AB = A & B; // never ->AB : Symbol(AB, Decl(intersectionReduction.ts, 40, 13)) +>AB : Symbol(AB, Decl(intersectionReduction.ts, 41, 13)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) type BC = B & C; // never ->BC : Symbol(BC, Decl(intersectionReduction.ts, 42, 16)) +>BC : Symbol(BC, Decl(intersectionReduction.ts, 43, 16)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) >C : Symbol(C, Decl(intersectionReduction.ts, 33, 36)) type U1 = Partial; // never ->U1 : Symbol(U1, Decl(intersectionReduction.ts, 43, 16)) +>U1 : Symbol(U1, Decl(intersectionReduction.ts, 44, 16)) >Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) type U2 = Readonly; // never ->U2 : Symbol(U2, Decl(intersectionReduction.ts, 45, 25)) +>U2 : Symbol(U2, Decl(intersectionReduction.ts, 46, 25)) >Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) type U3 = (A & B)['kind']; // never ->U3 : Symbol(U3, Decl(intersectionReduction.ts, 46, 26)) +>U3 : Symbol(U3, Decl(intersectionReduction.ts, 47, 26)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) type U4 = A & B | B & C; // never ->U4 : Symbol(U4, Decl(intersectionReduction.ts, 47, 26)) +>U4 : Symbol(U4, Decl(intersectionReduction.ts, 48, 26)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) >C : Symbol(C, Decl(intersectionReduction.ts, 33, 36)) type U5 = A | B & C; // A ->U5 : Symbol(U5, Decl(intersectionReduction.ts, 48, 24)) +>U5 : Symbol(U5, Decl(intersectionReduction.ts, 49, 24)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) >C : Symbol(C, Decl(intersectionReduction.ts, 33, 36)) type K1 = keyof (A & B); // string | number | symbol ->K1 : Symbol(K1, Decl(intersectionReduction.ts, 49, 20)) +>K1 : Symbol(K1, Decl(intersectionReduction.ts, 50, 20)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) type K2 = keyof A | keyof B; // 'kind' | 'foo' ->K2 : Symbol(K2, Decl(intersectionReduction.ts, 51, 24)) +>K2 : Symbol(K2, Decl(intersectionReduction.ts, 52, 24)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) >B : Symbol(B, Decl(intersectionReduction.ts, 32, 36)) type Merge1 = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] } ->Merge1 : Symbol(Merge1, Decl(intersectionReduction.ts, 52, 28)) ->T : Symbol(T, Decl(intersectionReduction.ts, 54, 12)) ->U : Symbol(U, Decl(intersectionReduction.ts, 54, 14)) ->P : Symbol(P, Decl(intersectionReduction.ts, 54, 23)) ->T : Symbol(T, Decl(intersectionReduction.ts, 54, 12)) ->U : Symbol(U, Decl(intersectionReduction.ts, 54, 14)) ->P : Symbol(P, Decl(intersectionReduction.ts, 54, 23)) ->T : Symbol(T, Decl(intersectionReduction.ts, 54, 12)) ->T : Symbol(T, Decl(intersectionReduction.ts, 54, 12)) ->P : Symbol(P, Decl(intersectionReduction.ts, 54, 23)) ->U : Symbol(U, Decl(intersectionReduction.ts, 54, 14)) ->P : Symbol(P, Decl(intersectionReduction.ts, 54, 23)) ->U : Symbol(U, Decl(intersectionReduction.ts, 54, 14)) - -type Merge2 = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] } ->Merge2 : Symbol(Merge2, Decl(intersectionReduction.ts, 54, 87)) +>Merge1 : Symbol(Merge1, Decl(intersectionReduction.ts, 53, 28)) >T : Symbol(T, Decl(intersectionReduction.ts, 55, 12)) >U : Symbol(U, Decl(intersectionReduction.ts, 55, 14)) >P : Symbol(P, Decl(intersectionReduction.ts, 55, 23)) @@ -207,169 +195,184 @@ type Merge2 = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & >P : Symbol(P, Decl(intersectionReduction.ts, 55, 23)) >U : Symbol(U, Decl(intersectionReduction.ts, 55, 14)) +type Merge2 = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] } +>Merge2 : Symbol(Merge2, Decl(intersectionReduction.ts, 55, 87)) +>T : Symbol(T, Decl(intersectionReduction.ts, 56, 12)) +>U : Symbol(U, Decl(intersectionReduction.ts, 56, 14)) +>P : Symbol(P, Decl(intersectionReduction.ts, 56, 23)) +>T : Symbol(T, Decl(intersectionReduction.ts, 56, 12)) +>U : Symbol(U, Decl(intersectionReduction.ts, 56, 14)) +>P : Symbol(P, Decl(intersectionReduction.ts, 56, 23)) +>T : Symbol(T, Decl(intersectionReduction.ts, 56, 12)) +>T : Symbol(T, Decl(intersectionReduction.ts, 56, 12)) +>P : Symbol(P, Decl(intersectionReduction.ts, 56, 23)) +>U : Symbol(U, Decl(intersectionReduction.ts, 56, 14)) +>P : Symbol(P, Decl(intersectionReduction.ts, 56, 23)) +>U : Symbol(U, Decl(intersectionReduction.ts, 56, 14)) + type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never ->M1 : Symbol(M1, Decl(intersectionReduction.ts, 55, 91)) ->a : Symbol(a, Decl(intersectionReduction.ts, 57, 11)) ->b : Symbol(b, Decl(intersectionReduction.ts, 57, 17)) ->a : Symbol(a, Decl(intersectionReduction.ts, 57, 28)) ->c : Symbol(c, Decl(intersectionReduction.ts, 57, 34)) +>M1 : Symbol(M1, Decl(intersectionReduction.ts, 56, 91)) +>a : Symbol(a, Decl(intersectionReduction.ts, 58, 11)) +>b : Symbol(b, Decl(intersectionReduction.ts, 58, 17)) +>a : Symbol(a, Decl(intersectionReduction.ts, 58, 28)) +>c : Symbol(c, Decl(intersectionReduction.ts, 58, 34)) type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {} ->M2 : Symbol(M2, Decl(intersectionReduction.ts, 57, 42)) ->Merge1 : Symbol(Merge1, Decl(intersectionReduction.ts, 52, 28)) ->a : Symbol(a, Decl(intersectionReduction.ts, 58, 18)) ->b : Symbol(b, Decl(intersectionReduction.ts, 58, 24)) ->a : Symbol(a, Decl(intersectionReduction.ts, 58, 34)) ->c : Symbol(c, Decl(intersectionReduction.ts, 58, 40)) - -type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 } ->M3 : Symbol(M3, Decl(intersectionReduction.ts, 58, 49)) ->Merge2 : Symbol(Merge2, Decl(intersectionReduction.ts, 54, 87)) +>M2 : Symbol(M2, Decl(intersectionReduction.ts, 58, 42)) +>Merge1 : Symbol(Merge1, Decl(intersectionReduction.ts, 53, 28)) >a : Symbol(a, Decl(intersectionReduction.ts, 59, 18)) >b : Symbol(b, Decl(intersectionReduction.ts, 59, 24)) >a : Symbol(a, Decl(intersectionReduction.ts, 59, 34)) >c : Symbol(c, Decl(intersectionReduction.ts, 59, 40)) -type D = { kind: 'd', foo: unknown }; ->D : Symbol(D, Decl(intersectionReduction.ts, 59, 49)) ->kind : Symbol(kind, Decl(intersectionReduction.ts, 61, 10)) ->foo : Symbol(foo, Decl(intersectionReduction.ts, 61, 21)) +type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 } +>M3 : Symbol(M3, Decl(intersectionReduction.ts, 59, 49)) +>Merge2 : Symbol(Merge2, Decl(intersectionReduction.ts, 55, 87)) +>a : Symbol(a, Decl(intersectionReduction.ts, 60, 18)) +>b : Symbol(b, Decl(intersectionReduction.ts, 60, 24)) +>a : Symbol(a, Decl(intersectionReduction.ts, 60, 34)) +>c : Symbol(c, Decl(intersectionReduction.ts, 60, 40)) -type E = { kind: 'e', foo: unknown }; ->E : Symbol(E, Decl(intersectionReduction.ts, 61, 37)) +type D = { kind: 'd', foo: unknown }; +>D : Symbol(D, Decl(intersectionReduction.ts, 60, 49)) >kind : Symbol(kind, Decl(intersectionReduction.ts, 62, 10)) >foo : Symbol(foo, Decl(intersectionReduction.ts, 62, 21)) +type E = { kind: 'e', foo: unknown }; +>E : Symbol(E, Decl(intersectionReduction.ts, 62, 37)) +>kind : Symbol(kind, Decl(intersectionReduction.ts, 63, 10)) +>foo : Symbol(foo, Decl(intersectionReduction.ts, 63, 21)) + declare function f10(x: { foo: T }): T; ->f10 : Symbol(f10, Decl(intersectionReduction.ts, 62, 37)) ->T : Symbol(T, Decl(intersectionReduction.ts, 64, 21)) ->x : Symbol(x, Decl(intersectionReduction.ts, 64, 24)) ->foo : Symbol(foo, Decl(intersectionReduction.ts, 64, 28)) ->T : Symbol(T, Decl(intersectionReduction.ts, 64, 21)) ->T : Symbol(T, Decl(intersectionReduction.ts, 64, 21)) +>f10 : Symbol(f10, Decl(intersectionReduction.ts, 63, 37)) +>T : Symbol(T, Decl(intersectionReduction.ts, 65, 21)) +>x : Symbol(x, Decl(intersectionReduction.ts, 65, 24)) +>foo : Symbol(foo, Decl(intersectionReduction.ts, 65, 28)) +>T : Symbol(T, Decl(intersectionReduction.ts, 65, 21)) +>T : Symbol(T, Decl(intersectionReduction.ts, 65, 21)) declare let a1: A | D; ->a1 : Symbol(a1, Decl(intersectionReduction.ts, 66, 11)) +>a1 : Symbol(a1, Decl(intersectionReduction.ts, 67, 11)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) ->D : Symbol(D, Decl(intersectionReduction.ts, 59, 49)) +>D : Symbol(D, Decl(intersectionReduction.ts, 60, 49)) declare let a2: A | D & E; ->a2 : Symbol(a2, Decl(intersectionReduction.ts, 67, 11)) +>a2 : Symbol(a2, Decl(intersectionReduction.ts, 68, 11)) >A : Symbol(A, Decl(intersectionReduction.ts, 30, 28)) ->D : Symbol(D, Decl(intersectionReduction.ts, 59, 49)) ->E : Symbol(E, Decl(intersectionReduction.ts, 61, 37)) +>D : Symbol(D, Decl(intersectionReduction.ts, 60, 49)) +>E : Symbol(E, Decl(intersectionReduction.ts, 62, 37)) let r1 = f10(a1); // unknown ->r1 : Symbol(r1, Decl(intersectionReduction.ts, 69, 3)) ->f10 : Symbol(f10, Decl(intersectionReduction.ts, 62, 37)) ->a1 : Symbol(a1, Decl(intersectionReduction.ts, 66, 11)) +>r1 : Symbol(r1, Decl(intersectionReduction.ts, 70, 3)) +>f10 : Symbol(f10, Decl(intersectionReduction.ts, 63, 37)) +>a1 : Symbol(a1, Decl(intersectionReduction.ts, 67, 11)) let r2 = f10(a2); // string ->r2 : Symbol(r2, Decl(intersectionReduction.ts, 70, 3)) ->f10 : Symbol(f10, Decl(intersectionReduction.ts, 62, 37)) ->a2 : Symbol(a2, Decl(intersectionReduction.ts, 67, 11)) +>r2 : Symbol(r2, Decl(intersectionReduction.ts, 71, 3)) +>f10 : Symbol(f10, Decl(intersectionReduction.ts, 63, 37)) +>a2 : Symbol(a2, Decl(intersectionReduction.ts, 68, 11)) // Repro from #31663 const x1 = { a: 'foo', b: 42 }; ->x1 : Symbol(x1, Decl(intersectionReduction.ts, 74, 5)) ->a : Symbol(a, Decl(intersectionReduction.ts, 74, 12)) ->b : Symbol(b, Decl(intersectionReduction.ts, 74, 22)) - -const x2 = { a: 'foo', b: true }; ->x2 : Symbol(x2, Decl(intersectionReduction.ts, 75, 5)) +>x1 : Symbol(x1, Decl(intersectionReduction.ts, 75, 5)) >a : Symbol(a, Decl(intersectionReduction.ts, 75, 12)) >b : Symbol(b, Decl(intersectionReduction.ts, 75, 22)) +const x2 = { a: 'foo', b: true }; +>x2 : Symbol(x2, Decl(intersectionReduction.ts, 76, 5)) +>a : Symbol(a, Decl(intersectionReduction.ts, 76, 12)) +>b : Symbol(b, Decl(intersectionReduction.ts, 76, 22)) + declare let k: 'a' | 'b'; ->k : Symbol(k, Decl(intersectionReduction.ts, 77, 11)) +>k : Symbol(k, Decl(intersectionReduction.ts, 78, 11)) x1[k] = 'bar' as any; // Error ->x1 : Symbol(x1, Decl(intersectionReduction.ts, 74, 5)) ->k : Symbol(k, Decl(intersectionReduction.ts, 77, 11)) +>x1 : Symbol(x1, Decl(intersectionReduction.ts, 75, 5)) +>k : Symbol(k, Decl(intersectionReduction.ts, 78, 11)) x2[k] = 'bar' as any; // Error ->x2 : Symbol(x2, Decl(intersectionReduction.ts, 75, 5)) ->k : Symbol(k, Decl(intersectionReduction.ts, 77, 11)) +>x2 : Symbol(x2, Decl(intersectionReduction.ts, 76, 5)) +>k : Symbol(k, Decl(intersectionReduction.ts, 78, 11)) const enum Tag1 {} ->Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 80, 21)) +>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 81, 21)) const enum Tag2 {} ->Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 82, 18)) +>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 83, 18)) declare let s1: string & Tag1; ->s1 : Symbol(s1, Decl(intersectionReduction.ts, 85, 11)) ->Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 80, 21)) +>s1 : Symbol(s1, Decl(intersectionReduction.ts, 86, 11)) +>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 81, 21)) declare let s2: string & Tag2; ->s2 : Symbol(s2, Decl(intersectionReduction.ts, 86, 11)) ->Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 82, 18)) +>s2 : Symbol(s2, Decl(intersectionReduction.ts, 87, 11)) +>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 83, 18)) declare let t1: string & Tag1 | undefined; ->t1 : Symbol(t1, Decl(intersectionReduction.ts, 88, 11)) ->Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 80, 21)) +>t1 : Symbol(t1, Decl(intersectionReduction.ts, 89, 11)) +>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 81, 21)) declare let t2: string & Tag2 | undefined; ->t2 : Symbol(t2, Decl(intersectionReduction.ts, 89, 11)) ->Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 82, 18)) +>t2 : Symbol(t2, Decl(intersectionReduction.ts, 90, 11)) +>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 83, 18)) s1 = s2; ->s1 : Symbol(s1, Decl(intersectionReduction.ts, 85, 11)) ->s2 : Symbol(s2, Decl(intersectionReduction.ts, 86, 11)) +>s1 : Symbol(s1, Decl(intersectionReduction.ts, 86, 11)) +>s2 : Symbol(s2, Decl(intersectionReduction.ts, 87, 11)) s2 = s1; ->s2 : Symbol(s2, Decl(intersectionReduction.ts, 86, 11)) ->s1 : Symbol(s1, Decl(intersectionReduction.ts, 85, 11)) +>s2 : Symbol(s2, Decl(intersectionReduction.ts, 87, 11)) +>s1 : Symbol(s1, Decl(intersectionReduction.ts, 86, 11)) t1 = t2; ->t1 : Symbol(t1, Decl(intersectionReduction.ts, 88, 11)) ->t2 : Symbol(t2, Decl(intersectionReduction.ts, 89, 11)) +>t1 : Symbol(t1, Decl(intersectionReduction.ts, 89, 11)) +>t2 : Symbol(t2, Decl(intersectionReduction.ts, 90, 11)) t2 = t1; ->t2 : Symbol(t2, Decl(intersectionReduction.ts, 89, 11)) ->t1 : Symbol(t1, Decl(intersectionReduction.ts, 88, 11)) +>t2 : Symbol(t2, Decl(intersectionReduction.ts, 90, 11)) +>t1 : Symbol(t1, Decl(intersectionReduction.ts, 89, 11)) // Repro from #36736 const f1 = (t: "a" | ("b" & "c")): "a" => t; ->f1 : Symbol(f1, Decl(intersectionReduction.ts, 99, 5)) ->t : Symbol(t, Decl(intersectionReduction.ts, 99, 12)) ->t : Symbol(t, Decl(intersectionReduction.ts, 99, 12)) +>f1 : Symbol(f1, Decl(intersectionReduction.ts, 100, 5)) +>t : Symbol(t, Decl(intersectionReduction.ts, 100, 12)) +>t : Symbol(t, Decl(intersectionReduction.ts, 100, 12)) type Container = { ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->Type : Symbol(Type, Decl(intersectionReduction.ts, 101, 15)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>Type : Symbol(Type, Decl(intersectionReduction.ts, 102, 15)) type: Type; ->type : Symbol(type, Decl(intersectionReduction.ts, 101, 39)) ->Type : Symbol(Type, Decl(intersectionReduction.ts, 101, 15)) +>type : Symbol(type, Decl(intersectionReduction.ts, 102, 39)) +>Type : Symbol(Type, Decl(intersectionReduction.ts, 102, 15)) } const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t; ->f2 : Symbol(f2, Decl(intersectionReduction.ts, 105, 5)) ->t : Symbol(t, Decl(intersectionReduction.ts, 105, 12)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->t : Symbol(t, Decl(intersectionReduction.ts, 105, 12)) - -const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t; ->f3 : Symbol(f3, Decl(intersectionReduction.ts, 106, 5)) +>f2 : Symbol(f2, Decl(intersectionReduction.ts, 106, 5)) >t : Symbol(t, Decl(intersectionReduction.ts, 106, 12)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->dataB : Symbol(dataB, Decl(intersectionReduction.ts, 106, 51)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) >t : Symbol(t, Decl(intersectionReduction.ts, 106, 12)) -const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t; ->f4 : Symbol(f4, Decl(intersectionReduction.ts, 107, 5)) +const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t; +>f3 : Symbol(f3, Decl(intersectionReduction.ts, 107, 5)) >t : Symbol(t, Decl(intersectionReduction.ts, 107, 12)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) ->dataB : Symbol(dataB, Decl(intersectionReduction.ts, 107, 43)) ->Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>dataB : Symbol(dataB, Decl(intersectionReduction.ts, 107, 51)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) >t : Symbol(t, Decl(intersectionReduction.ts, 107, 12)) +const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t; +>f4 : Symbol(f4, Decl(intersectionReduction.ts, 108, 5)) +>t : Symbol(t, Decl(intersectionReduction.ts, 108, 12)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>dataB : Symbol(dataB, Decl(intersectionReduction.ts, 108, 43)) +>Container : Symbol(Container, Decl(intersectionReduction.ts, 100, 44)) +>t : Symbol(t, Decl(intersectionReduction.ts, 108, 12)) + diff --git a/tests/baselines/reference/intersectionReduction.types b/tests/baselines/reference/intersectionReduction.types index 7bb24e68351ad..5976fdf48fc6f 100644 --- a/tests/baselines/reference/intersectionReduction.types +++ b/tests/baselines/reference/intersectionReduction.types @@ -111,6 +111,11 @@ ab.kind; // Error >ab : never >kind : any +ab = 42; +>ab = 42 : 42 +>ab : never +>42 : 42 + declare let x: A | (B & C); // A >x : A diff --git a/tests/baselines/reference/intersectionReductionStrict.errors.txt b/tests/baselines/reference/intersectionReductionStrict.errors.txt index fe3e67fdc2ea7..c46c604a00b9b 100644 --- a/tests/baselines/reference/intersectionReductionStrict.errors.txt +++ b/tests/baselines/reference/intersectionReductionStrict.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(38,4): error TS2339: Property 'kind' does not exist on type 'never'. + The type 'never' was reduced from the intersection 'A & B'. Each type of that intersection has properties that conflict, so values of that type can never exist. tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(69,1): error TS2322: Type 'any' is not assignable to type 'never'. tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(70,1): error TS2322: Type 'any' is not assignable to type 'never'. @@ -44,6 +45,7 @@ tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(70,1): ab.kind; // Error ~~~~ !!! error TS2339: Property 'kind' does not exist on type 'never'. +!!! error TS2339: The type 'never' was reduced from the intersection 'A & B'. Each type of that intersection has properties that conflict, so values of that type can never exist. declare let x: A | (B & C); // A let a: A = x; diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt b/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt index dfcb8a598dae5..75a40aa821bc8 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt +++ b/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type 'never'. + The type 'never' was reduced from the intersection 'I & RegExp'. Each type of that intersection has properties that conflict, so values of that type can never exist. ==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts (1 errors) ==== @@ -11,4 +12,5 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20) } else if (!result.global) { ~~~~~~ !!! error TS2339: Property 'global' does not exist on type 'never'. +!!! error TS2339: The type 'never' was reduced from the intersection 'I & RegExp'. Each type of that intersection has properties that conflict, so values of that type can never exist. } \ No newline at end of file diff --git a/tests/cases/conformance/types/intersection/intersectionReduction.ts b/tests/cases/conformance/types/intersection/intersectionReduction.ts index 8aeb110fd5f10..19d3bd84b43fe 100644 --- a/tests/cases/conformance/types/intersection/intersectionReduction.ts +++ b/tests/cases/conformance/types/intersection/intersectionReduction.ts @@ -38,6 +38,7 @@ type C = { kind: 'c', foo: number }; declare let ab: A & B; ab.kind; // Error +ab = 42; declare let x: A | (B & C); // A let a: A = x;