Add isIntersectionConstituent to relation key (#34789)
* Add isIntersectionConstituent to relation key isIntersectionConstituent controls whether relation checking performs excess property and common property checks. It is possible to fail a relation check with excess property checks turned on, cache the result, and then skip a relation check with excess property checks that would have succeeded. #33133 provides an example of such a program. Fixes #33133 the right way, so I reverted the fix at #33213 Fixes #34762 (by reverting #33213) Fixes #33944 -- I added the test from #34646 * Update comments in test
This commit is contained in:
parent
7635884224
commit
00dd1f0609
|
@ -14165,7 +14165,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);
|
||||
}
|
||||
|
@ -14571,7 +14571,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 {
|
||||
|
@ -14609,7 +14609,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(<IntersectionType>source, target, /*reportErrors*/ false, /*isIntersectionConstituent*/ true);
|
||||
result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false);
|
||||
}
|
||||
if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) {
|
||||
if (result = recursiveTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent)) {
|
||||
|
@ -14903,14 +14903,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;
|
||||
}
|
||||
|
@ -14997,7 +14997,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)) {
|
||||
|
@ -16211,17 +16211,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<RelationComparisonResult>) {
|
||||
function getRelationKey(source: Type, target: Type, isIntersectionConstituent: boolean, relation: Map<RelationComparisonResult>) {
|
||||
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(<TypeReference>source, typeParameters) + "," + getTypeReferenceId(<TypeReference>target, typeParameters);
|
||||
return getTypeReferenceId(<TypeReference>source, typeParameters) + "," + getTypeReferenceId(<TypeReference>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
|
||||
|
|
26
tests/baselines/reference/commonTypeIntersection.errors.txt
Normal file
26
tests/baselines/reference/commonTypeIntersection.errors.txt
Normal file
|
@ -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"'.
|
||||
|
10
tests/baselines/reference/commonTypeIntersection.js
Normal file
10
tests/baselines/reference/commonTypeIntersection.js
Normal file
|
@ -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
|
21
tests/baselines/reference/commonTypeIntersection.symbols
Normal file
21
tests/baselines/reference/commonTypeIntersection.symbols
Normal file
|
@ -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))
|
||||
|
21
tests/baselines/reference/commonTypeIntersection.types
Normal file
21
tests/baselines/reference/commonTypeIntersection.types
Normal file
|
@ -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
|
||||
|
|
@ -5,20 +5,23 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t
|
|||
Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
|
||||
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
|
||||
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
Type 'T' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["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<T, TextChannel>["type"]'.
|
||||
Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["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<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["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<T, TextChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["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');
|
||||
|
|
|
@ -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)'.
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
//// [intersectionMemberOfUnionNarrowsCorrectly.ts]
|
||||
export type U = { kind?: 'A', a: string } | { kind?: 'B' } & { b: string };
|
||||
type Ex<T, U> = T extends U ? T : never;
|
||||
declare let x: Ex<U, { kind?: 'A' }>
|
||||
x.a
|
||||
|
||||
|
||||
//// [intersectionMemberOfUnionNarrowsCorrectly.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
x.a;
|
|
@ -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, U> = 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<U, { kind?: 'A' }>
|
||||
>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))
|
||||
|
|
@ -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, U> = T extends U ? T : never;
|
||||
>Ex : Ex<T, U>
|
||||
|
||||
declare let x: Ex<U, { kind?: 'A' }>
|
||||
>x : { kind?: "A"; a: string; }
|
||||
>kind : "A"
|
||||
|
||||
x.a
|
||||
>x.a : string
|
||||
>x : { kind?: "A"; a: string; }
|
||||
>a : string
|
||||
|
|
@ -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 = <I3>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 = <I2>z;
|
||||
var d = <I1>y;
|
||||
|
|
@ -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'.
|
||||
}
|
||||
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
export type U = { kind?: 'A', a: string } | { kind?: 'B' } & { b: string };
|
||||
type Ex<T, U> = T extends U ? T : never;
|
||||
declare let x: Ex<U, { kind?: 'A' }>
|
||||
x.a
|
Loading…
Reference in a new issue