diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2666c0f590f7e..8ee7f81890e61 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14157,7 +14157,7 @@ namespace ts { return true; } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { - const related = relation.get(getRelationKey(source, target, relation)); + const related = relation.get(getRelationKey(source, target, /*isIntersectionConstituent*/ false, relation)); if (related !== undefined) { return !!(related & RelationComparisonResult.Succeeded); } @@ -14563,7 +14563,7 @@ namespace ts { // and we need to handle "each" relations before "some" relations for the same kind of type. if (source.flags & TypeFlags.Union) { result = relation === comparableRelation ? - someTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), isIntersectionConstituent) : + someTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive)) : eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive)); } else { @@ -14601,7 +14601,7 @@ namespace ts { // // - For a primitive type or type parameter (such as 'number = A & B') there is no point in // breaking the intersection apart. - result = someTypeRelatedToType(source, target, /*reportErrors*/ false, /*isIntersectionConstituent*/ true); + result = someTypeRelatedToType(source, target, /*reportErrors*/ false); } if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) { if (result = recursiveTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent)) { @@ -14895,14 +14895,14 @@ namespace ts { return result; } - function someTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean, isIntersectionConstituent: boolean): Ternary { + function someTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean): Ternary { const sourceTypes = source.types; if (source.flags & TypeFlags.Union && containsType(sourceTypes, target)) { return Ternary.True; } const len = sourceTypes.length; for (let i = 0; i < len; i++) { - const related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1, /*headMessage*/ undefined, isIntersectionConstituent); + const related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1); if (related) { return related; } @@ -14989,7 +14989,7 @@ namespace ts { if (overflow) { return Ternary.False; } - const id = getRelationKey(source, target, relation); + const id = getRelationKey(source, target, isIntersectionConstituent, relation); const entry = relation.get(id); if (entry !== undefined) { if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Reported)) { @@ -16203,17 +16203,18 @@ namespace ts { * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters. * For other cases, the types ids are used. */ - function getRelationKey(source: Type, target: Type, relation: Map) { + function getRelationKey(source: Type, target: Type, isIntersectionConstituent: boolean, relation: Map) { if (relation === identityRelation && source.id > target.id) { const temp = source; source = target; target = temp; } + const intersection = isIntersectionConstituent ? "&" : ""; if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { const typeParameters: Type[] = []; - return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); + return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters) + intersection; } - return source.id + "," + target.id; + return source.id + "," + target.id + intersection; } // Invoke the callback for each underlying property symbol of the given symbol and return the first diff --git a/tests/baselines/reference/commonTypeIntersection.errors.txt b/tests/baselines/reference/commonTypeIntersection.errors.txt new file mode 100644 index 0000000000000..c10f8e2cfeca3 --- /dev/null +++ b/tests/baselines/reference/commonTypeIntersection.errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/types/intersection/commonTypeIntersection.ts(2,5): error TS2322: Type '{ __typename?: "TypeTwo"; } & { a: boolean; }' is not assignable to type '{ __typename?: "TypeOne"; } & { a: boolean; }'. + Type '{ __typename?: "TypeTwo"; } & { a: boolean; }' is not assignable to type '{ __typename?: "TypeOne"; }'. + Types of property '__typename' are incompatible. + Type '"TypeTwo"' is not assignable to type '"TypeOne"'. +tests/cases/conformance/types/intersection/commonTypeIntersection.ts(4,5): error TS2322: Type '{ __typename?: "TypeTwo"; } & string' is not assignable to type '{ __typename?: "TypeOne"; } & string'. + Type '{ __typename?: "TypeTwo"; } & string' is not assignable to type '{ __typename?: "TypeOne"; }'. + Types of property '__typename' are incompatible. + Type '"TypeTwo"' is not assignable to type '"TypeOne"'. + + +==== tests/cases/conformance/types/intersection/commonTypeIntersection.ts (2 errors) ==== + declare let x1: { __typename?: 'TypeTwo' } & { a: boolean }; + let y1: { __typename?: 'TypeOne' } & { a: boolean} = x1; // should error here + ~~ +!!! error TS2322: Type '{ __typename?: "TypeTwo"; } & { a: boolean; }' is not assignable to type '{ __typename?: "TypeOne"; } & { a: boolean; }'. +!!! error TS2322: Type '{ __typename?: "TypeTwo"; } & { a: boolean; }' is not assignable to type '{ __typename?: "TypeOne"; }'. +!!! error TS2322: Types of property '__typename' are incompatible. +!!! error TS2322: Type '"TypeTwo"' is not assignable to type '"TypeOne"'. + declare let x2: { __typename?: 'TypeTwo' } & string; + let y2: { __typename?: 'TypeOne' } & string = x2; // should error here + ~~ +!!! error TS2322: Type '{ __typename?: "TypeTwo"; } & string' is not assignable to type '{ __typename?: "TypeOne"; } & string'. +!!! error TS2322: Type '{ __typename?: "TypeTwo"; } & string' is not assignable to type '{ __typename?: "TypeOne"; }'. +!!! error TS2322: Types of property '__typename' are incompatible. +!!! error TS2322: Type '"TypeTwo"' is not assignable to type '"TypeOne"'. + \ No newline at end of file diff --git a/tests/baselines/reference/commonTypeIntersection.js b/tests/baselines/reference/commonTypeIntersection.js new file mode 100644 index 0000000000000..1bef2b3b06c05 --- /dev/null +++ b/tests/baselines/reference/commonTypeIntersection.js @@ -0,0 +1,10 @@ +//// [commonTypeIntersection.ts] +declare let x1: { __typename?: 'TypeTwo' } & { a: boolean }; +let y1: { __typename?: 'TypeOne' } & { a: boolean} = x1; // should error here +declare let x2: { __typename?: 'TypeTwo' } & string; +let y2: { __typename?: 'TypeOne' } & string = x2; // should error here + + +//// [commonTypeIntersection.js] +var y1 = x1; // should error here +var y2 = x2; // should error here diff --git a/tests/baselines/reference/commonTypeIntersection.symbols b/tests/baselines/reference/commonTypeIntersection.symbols new file mode 100644 index 0000000000000..3c81f5f450848 --- /dev/null +++ b/tests/baselines/reference/commonTypeIntersection.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/types/intersection/commonTypeIntersection.ts === +declare let x1: { __typename?: 'TypeTwo' } & { a: boolean }; +>x1 : Symbol(x1, Decl(commonTypeIntersection.ts, 0, 11)) +>__typename : Symbol(__typename, Decl(commonTypeIntersection.ts, 0, 17)) +>a : Symbol(a, Decl(commonTypeIntersection.ts, 0, 46)) + +let y1: { __typename?: 'TypeOne' } & { a: boolean} = x1; // should error here +>y1 : Symbol(y1, Decl(commonTypeIntersection.ts, 1, 3)) +>__typename : Symbol(__typename, Decl(commonTypeIntersection.ts, 1, 9)) +>a : Symbol(a, Decl(commonTypeIntersection.ts, 1, 38)) +>x1 : Symbol(x1, Decl(commonTypeIntersection.ts, 0, 11)) + +declare let x2: { __typename?: 'TypeTwo' } & string; +>x2 : Symbol(x2, Decl(commonTypeIntersection.ts, 2, 11)) +>__typename : Symbol(__typename, Decl(commonTypeIntersection.ts, 2, 17)) + +let y2: { __typename?: 'TypeOne' } & string = x2; // should error here +>y2 : Symbol(y2, Decl(commonTypeIntersection.ts, 3, 3)) +>__typename : Symbol(__typename, Decl(commonTypeIntersection.ts, 3, 9)) +>x2 : Symbol(x2, Decl(commonTypeIntersection.ts, 2, 11)) + diff --git a/tests/baselines/reference/commonTypeIntersection.types b/tests/baselines/reference/commonTypeIntersection.types new file mode 100644 index 0000000000000..aa14b244bb062 --- /dev/null +++ b/tests/baselines/reference/commonTypeIntersection.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/types/intersection/commonTypeIntersection.ts === +declare let x1: { __typename?: 'TypeTwo' } & { a: boolean }; +>x1 : { __typename?: "TypeTwo"; } & { a: boolean; } +>__typename : "TypeTwo" +>a : boolean + +let y1: { __typename?: 'TypeOne' } & { a: boolean} = x1; // should error here +>y1 : { __typename?: "TypeOne"; } & { a: boolean; } +>__typename : "TypeOne" +>a : boolean +>x1 : { __typename?: "TypeTwo"; } & { a: boolean; } + +declare let x2: { __typename?: 'TypeTwo' } & string; +>x2 : { __typename?: "TypeTwo"; } & string +>__typename : "TypeTwo" + +let y2: { __typename?: 'TypeOne' } & string = x2; // should error here +>y2 : { __typename?: "TypeOne"; } & string +>__typename : "TypeOne" +>x2 : { __typename?: "TypeTwo"; } & string + diff --git a/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt b/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt index af63c18523d6a..9abaa6db80393 100644 --- a/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt +++ b/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt @@ -5,20 +5,23 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"] & ChannelOfType["type"]'. Type '"text"' is not assignable to type 'ChannelOfType["type"] & ChannelOfType["type"]'. Type '"text"' is not assignable to type 'ChannelOfType["type"]'. - Type 'T' is not assignable to type 'ChannelOfType["type"]'. - Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"]'. - Type '"text"' is not assignable to type 'ChannelOfType["type"]'. - Type '"text"' is not assignable to type 'T & "text"'. - Type '"text"' is not assignable to type 'T'. - '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. - Type 'T' is not assignable to type 'T & "text"'. - Type '"text" | "email"' is not assignable to type 'T & "text"'. - Type '"text"' is not assignable to type 'T & "text"'. - Type '"text"' is not assignable to type 'T'. - '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. - Type 'T' is not assignable to type '"text"'. - Type '"text" | "email"' is not assignable to type '"text"'. - Type '"email"' is not assignable to type '"text"'. + Type '"text"' is not assignable to type 'T & "text"'. + Type '"text"' is not assignable to type 'T'. + '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. + Type 'T' is not assignable to type 'ChannelOfType["type"]'. + Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"]'. + Type '"text"' is not assignable to type 'ChannelOfType["type"]'. + Type '"text"' is not assignable to type 'T & "text"'. + Type '"text"' is not assignable to type 'T'. + '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. + Type 'T' is not assignable to type 'T & "text"'. + Type '"text" | "email"' is not assignable to type 'T & "text"'. + Type '"text"' is not assignable to type 'T & "text"'. + Type '"text"' is not assignable to type 'T'. + '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. + Type 'T' is not assignable to type '"text"'. + Type '"text" | "email"' is not assignable to type '"text"'. + Type '"email"' is not assignable to type '"text"'. ==== tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.ts (1 errors) ==== @@ -63,20 +66,23 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t !!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"] & ChannelOfType["type"]'. !!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType["type"] & ChannelOfType["type"]'. !!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType["type"]'. -!!! error TS2322: Type 'T' is not assignable to type 'ChannelOfType["type"]'. -!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"]'. -!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType["type"]'. -!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text"' is not assignable to type 'T'. -!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. -!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text"' is not assignable to type 'T'. -!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. -!!! error TS2322: Type 'T' is not assignable to type '"text"'. -!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'. -!!! error TS2322: Type '"email"' is not assignable to type '"text"'. +!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text"' is not assignable to type 'T'. +!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. +!!! error TS2322: Type 'T' is not assignable to type 'ChannelOfType["type"]'. +!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"]'. +!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType["type"]'. +!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text"' is not assignable to type 'T'. +!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. +!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text"' is not assignable to type 'T'. +!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. +!!! error TS2322: Type 'T' is not assignable to type '"text"'. +!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'. +!!! error TS2322: Type '"email"' is not assignable to type '"text"'. } const newTextChannel = makeNewChannel('text'); diff --git a/tests/baselines/reference/intersectionAndUnionTypes.errors.txt b/tests/baselines/reference/intersectionAndUnionTypes.errors.txt index 4f3b1db01e305..7de8735f6406c 100644 --- a/tests/baselines/reference/intersectionAndUnionTypes.errors.txt +++ b/tests/baselines/reference/intersectionAndUnionTypes.errors.txt @@ -24,14 +24,14 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(29,1): e Property 'd' is missing in type 'A & B' but required in type 'D'. tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(31,1): error TS2322: Type 'A & B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. Type 'A & B' is not assignable to type 'B & D'. - Type 'A & B' is not assignable to type 'D'. + Property 'd' is missing in type 'A & B' but required in type 'D'. tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(32,1): error TS2322: Type 'A | B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. Type 'A' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. Type 'A' is not assignable to type 'A & D'. Property 'd' is missing in type 'A' but required in type 'D'. tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(33,1): error TS2322: Type 'C & D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. Type 'C & D' is not assignable to type 'B & D'. - Type 'C & D' is not assignable to type 'B'. + Property 'b' is missing in type 'C & D' but required in type 'B'. tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(34,1): error TS2322: Type 'C | D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. Type 'C' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. Type 'C' is not assignable to type 'B & C'. @@ -118,7 +118,8 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): e ~ !!! error TS2322: Type 'A & B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. !!! error TS2322: Type 'A & B' is not assignable to type 'B & D'. -!!! error TS2322: Type 'A & B' is not assignable to type 'D'. +!!! error TS2322: Property 'd' is missing in type 'A & B' but required in type 'D'. +!!! related TS2728 tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts:4:15: 'd' is declared here. y = aob; ~ !!! error TS2322: Type 'A | B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. @@ -130,7 +131,8 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): e ~ !!! error TS2322: Type 'C & D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. !!! error TS2322: Type 'C & D' is not assignable to type 'B & D'. -!!! error TS2322: Type 'C & D' is not assignable to type 'B'. +!!! error TS2322: Property 'b' is missing in type 'C & D' but required in type 'B'. +!!! related TS2728 tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts:2:15: 'b' is declared here. y = cod; ~ !!! error TS2322: Type 'C | D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'. diff --git a/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.js b/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.js new file mode 100644 index 0000000000000..059d182b1b2d1 --- /dev/null +++ b/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.js @@ -0,0 +1,11 @@ +//// [intersectionMemberOfUnionNarrowsCorrectly.ts] +export type U = { kind?: 'A', a: string } | { kind?: 'B' } & { b: string }; +type Ex = T extends U ? T : never; +declare let x: Ex +x.a + + +//// [intersectionMemberOfUnionNarrowsCorrectly.js] +"use strict"; +exports.__esModule = true; +x.a; diff --git a/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.symbols b/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.symbols new file mode 100644 index 0000000000000..d10772a93f56b --- /dev/null +++ b/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.symbols @@ -0,0 +1,27 @@ +=== tests/cases/conformance/types/intersection/intersectionMemberOfUnionNarrowsCorrectly.ts === +export type U = { kind?: 'A', a: string } | { kind?: 'B' } & { b: string }; +>U : Symbol(U, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 0)) +>kind : Symbol(kind, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 17)) +>a : Symbol(a, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 29)) +>kind : Symbol(kind, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 45)) +>b : Symbol(b, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 62)) + +type Ex = T extends U ? T : never; +>Ex : Symbol(Ex, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 75)) +>T : Symbol(T, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 1, 8)) +>U : Symbol(U, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 1, 10)) +>T : Symbol(T, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 1, 8)) +>U : Symbol(U, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 1, 10)) +>T : Symbol(T, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 1, 8)) + +declare let x: Ex +>x : Symbol(x, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 2, 11)) +>Ex : Symbol(Ex, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 75)) +>U : Symbol(U, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 0)) +>kind : Symbol(kind, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 2, 22)) + +x.a +>x.a : Symbol(a, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 29)) +>x : Symbol(x, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 2, 11)) +>a : Symbol(a, Decl(intersectionMemberOfUnionNarrowsCorrectly.ts, 0, 29)) + diff --git a/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.types b/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.types new file mode 100644 index 0000000000000..77805ece13b11 --- /dev/null +++ b/tests/baselines/reference/intersectionMemberOfUnionNarrowsCorrectly.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/types/intersection/intersectionMemberOfUnionNarrowsCorrectly.ts === +export type U = { kind?: 'A', a: string } | { kind?: 'B' } & { b: string }; +>U : U +>kind : "A" +>a : string +>kind : "B" +>b : string + +type Ex = T extends U ? T : never; +>Ex : Ex + +declare let x: Ex +>x : { kind?: "A"; a: string; } +>kind : "A" + +x.a +>x.a : string +>x : { kind?: "A"; a: string; } +>a : string + diff --git a/tests/baselines/reference/typeAssertionsWithIntersectionTypes01.errors.txt b/tests/baselines/reference/typeAssertionsWithIntersectionTypes01.errors.txt index 29a7f49d2dbe8..d7df5037490ae 100644 --- a/tests/baselines/reference/typeAssertionsWithIntersectionTypes01.errors.txt +++ b/tests/baselines/reference/typeAssertionsWithIntersectionTypes01.errors.txt @@ -1,6 +1,7 @@ tests/cases/conformance/types/typeRelationships/comparable/typeAssertionsWithIntersectionTypes01.ts(17,9): error TS2352: Conversion of type 'I2' to type 'I1 & I3' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property 'p3' is missing in type 'I2' but required in type 'I3'. tests/cases/conformance/types/typeRelationships/comparable/typeAssertionsWithIntersectionTypes01.ts(18,9): error TS2352: Conversion of type 'I2' to type 'I3' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. + Property 'p3' is missing in type 'I2' but required in type 'I3'. ==== tests/cases/conformance/types/typeRelationships/comparable/typeAssertionsWithIntersectionTypes01.ts (2 errors) ==== @@ -28,6 +29,8 @@ tests/cases/conformance/types/typeRelationships/comparable/typeAssertionsWithInt var b = z; ~~~~~ !!! error TS2352: Conversion of type 'I2' to type 'I3' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. +!!! error TS2352: Property 'p3' is missing in type 'I2' but required in type 'I3'. +!!! related TS2728 tests/cases/conformance/types/typeRelationships/comparable/typeAssertionsWithIntersectionTypes01.ts:10:5: 'p3' is declared here. var c = z; var d = y; \ No newline at end of file diff --git a/tests/baselines/reference/unionThisTypeInFunctions.errors.txt b/tests/baselines/reference/unionThisTypeInFunctions.errors.txt index db03a5426fb43..f4f0377a0874c 100644 --- a/tests/baselines/reference/unionThisTypeInFunctions.errors.txt +++ b/tests/baselines/reference/unionThisTypeInFunctions.errors.txt @@ -5,8 +5,12 @@ tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts(10,5): error Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. The 'this' types of each signature are incompatible. Type 'Fake' is not assignable to type 'Real'. - Types of property 'data' are incompatible. - Type 'number' is not assignable to type 'string'. + Types of property 'method' are incompatible. + Type '(this: Fake, n: number) => void' is not assignable to type '(this: Real, n: number) => void'. + The 'this' types of each signature are incompatible. + Type 'Real' is not assignable to type 'Fake'. + Types of property 'data' are incompatible. + Type 'string' is not assignable to type 'number'. ==== tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts (1 errors) ==== @@ -28,7 +32,11 @@ tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts(10,5): error !!! error TS2684: Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. !!! error TS2684: The 'this' types of each signature are incompatible. !!! error TS2684: Type 'Fake' is not assignable to type 'Real'. -!!! error TS2684: Types of property 'data' are incompatible. -!!! error TS2684: Type 'number' is not assignable to type 'string'. +!!! error TS2684: Types of property 'method' are incompatible. +!!! error TS2684: Type '(this: Fake, n: number) => void' is not assignable to type '(this: Real, n: number) => void'. +!!! error TS2684: The 'this' types of each signature are incompatible. +!!! error TS2684: Type 'Real' is not assignable to type 'Fake'. +!!! error TS2684: Types of property 'data' are incompatible. +!!! error TS2684: Type 'string' is not assignable to type 'number'. } \ No newline at end of file diff --git a/tests/cases/conformance/types/intersection/commonTypeIntersection.ts b/tests/cases/conformance/types/intersection/commonTypeIntersection.ts new file mode 100644 index 0000000000000..1b4ce3746bcad --- /dev/null +++ b/tests/cases/conformance/types/intersection/commonTypeIntersection.ts @@ -0,0 +1,4 @@ +declare let x1: { __typename?: 'TypeTwo' } & { a: boolean }; +let y1: { __typename?: 'TypeOne' } & { a: boolean} = x1; // should error here +declare let x2: { __typename?: 'TypeTwo' } & string; +let y2: { __typename?: 'TypeOne' } & string = x2; // should error here diff --git a/tests/cases/conformance/types/intersection/intersectionMemberOfUnionNarrowsCorrectly.ts b/tests/cases/conformance/types/intersection/intersectionMemberOfUnionNarrowsCorrectly.ts new file mode 100644 index 0000000000000..d2657011dae6b --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionMemberOfUnionNarrowsCorrectly.ts @@ -0,0 +1,4 @@ +export type U = { kind?: 'A', a: string } | { kind?: 'B' } & { b: string }; +type Ex = T extends U ? T : never; +declare let x: Ex +x.a