mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-13 06:20:23 -06:00
Merge pull request #11717 from Microsoft/normalizeIntersectionTypes
Normalize union/intersection type combinations
This commit is contained in:
commit
66857b5f8e
@ -5604,6 +5604,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// We normalize combinations of intersection and union types based on the distributive property of the '&'
|
||||
// operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
|
||||
// types with union type constituents into equivalent union types with intersection type constituents and
|
||||
// effectively ensure that union types are always at the top level in type representations.
|
||||
//
|
||||
// We do not perform structural deduplication on intersection types. Intersection types are created only by the &
|
||||
// type operator and we can't reduce those because we want to support recursive intersection types. For example,
|
||||
// a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
|
||||
@ -5613,6 +5618,15 @@ namespace ts {
|
||||
if (types.length === 0) {
|
||||
return emptyObjectType;
|
||||
}
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
const type = types[i];
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
|
||||
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
|
||||
return getUnionType(map((<UnionType>type).types, t => getIntersectionType(replaceElement(types, i, t))),
|
||||
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
}
|
||||
const typeSet = [] as TypeSet;
|
||||
addTypesToIntersection(typeSet, types);
|
||||
if (typeSet.containsAny) {
|
||||
@ -6560,7 +6574,9 @@ namespace ts {
|
||||
|
||||
const saveErrorInfo = errorInfo;
|
||||
|
||||
// Note that these checks are specifically ordered to produce correct results.
|
||||
// Note that these checks are specifically ordered to produce correct results. In particular,
|
||||
// we need to deconstruct unions before intersections (because unions are always at the top),
|
||||
// and we need to handle "each" relations before "some" relations for the same kind of type.
|
||||
if (source.flags & TypeFlags.Union) {
|
||||
if (relation === comparableRelation) {
|
||||
result = someTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive));
|
||||
@ -6568,44 +6584,36 @@ namespace ts {
|
||||
else {
|
||||
result = eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive));
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Union) {
|
||||
if (result = typeRelatedToSomeType(source, <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Intersection) {
|
||||
result = typeRelatedToEachType(source, target as IntersectionType, reportErrors);
|
||||
|
||||
if (result) {
|
||||
if (result = typeRelatedToEachType(source, target as IntersectionType, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// It is necessary to try these "some" checks on both sides because there may be nested "each" checks
|
||||
// on either side that need to be prioritized. For example, A | B = (A | B) & (C | D) or
|
||||
// A & B = (A & B) | (C & D).
|
||||
if (source.flags & TypeFlags.Intersection) {
|
||||
// Check to see if any constituents of the intersection are immediately related to the target.
|
||||
//
|
||||
// Don't report errors though. Checking whether a constituent is related to the source is not actually
|
||||
// useful and leads to some confusing error messages. Instead it is better to let the below checks
|
||||
// take care of this, or to not elaborate at all. For instance,
|
||||
//
|
||||
// - For an object type (such as 'C = A & B'), users are usually more interested in structural errors.
|
||||
//
|
||||
// - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection
|
||||
// than to report that 'D' is not assignable to 'A' or 'B'.
|
||||
//
|
||||
// - For a primitive type or type parameter (such as 'number = A & B') there is no point in
|
||||
// breaking the intersection apart.
|
||||
if (result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
if (result = typeRelatedToSomeType(source, <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive))) {
|
||||
return result;
|
||||
}
|
||||
else if (source.flags & TypeFlags.Intersection) {
|
||||
// Check to see if any constituents of the intersection are immediately related to the target.
|
||||
//
|
||||
// Don't report errors though. Checking whether a constituent is related to the source is not actually
|
||||
// useful and leads to some confusing error messages. Instead it is better to let the below checks
|
||||
// take care of this, or to not elaborate at all. For instance,
|
||||
//
|
||||
// - For an object type (such as 'C = A & B'), users are usually more interested in structural errors.
|
||||
//
|
||||
// - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection
|
||||
// than to report that 'D' is not assignable to 'A' or 'B'.
|
||||
//
|
||||
// - For a primitive type or type parameter (such as 'number = A & B') there is no point in
|
||||
// breaking the intersection apart.
|
||||
if (result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -532,6 +532,12 @@ namespace ts {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function replaceElement<T>(array: T[], index: number, value: T): T[] {
|
||||
const result = array.slice(0);
|
||||
result[index] = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a binary search, finding the index at which 'value' occurs in 'array'.
|
||||
* If no such index is found, returns the 2's-complement of first index at which
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(17,5): error TS2322: Type 'A & B' is not assignable to type 'number'.
|
||||
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(18,5): error TS2322: Type 'A & B' is not assignable to type 'boolean'.
|
||||
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(19,5): error TS2322: Type 'A & B' is not assignable to type 'string'.
|
||||
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Type 'number & boolean' is not assignable to type 'string'.
|
||||
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
|
||||
Type 'number & true' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/errorMessagesIntersectionTypes04.ts (4 errors) ====
|
||||
@ -33,5 +34,6 @@ tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Ty
|
||||
|
||||
str = num_and_bool;
|
||||
~~~
|
||||
!!! error TS2322: Type 'number & boolean' is not assignable to type 'string'.
|
||||
!!! error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
|
||||
!!! error TS2322: Type 'number & true' is not assignable to type 'string'.
|
||||
}
|
||||
@ -30,28 +30,29 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(29,1): e
|
||||
Type 'A & B' is not assignable to type 'C | D'.
|
||||
Type 'A & B' is not assignable to type 'D'.
|
||||
Property 'd' is missing in type 'A & B'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(31,1): error TS2322: Type 'A & B' is not assignable to type '(A | B) & (C | D)'.
|
||||
Type 'A & B' is not assignable to type 'C | 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'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(32,1): error TS2322: Type 'A | B' is not assignable to type '(A | B) & (C | D)'.
|
||||
Type 'A' is not assignable to type '(A | B) & (C | D)'.
|
||||
Type 'A' is not assignable to type 'C | D'.
|
||||
Type 'A' is not assignable to type 'D'.
|
||||
Property 'd' is missing in type 'A'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(33,1): error TS2322: Type 'C & D' is not assignable to type '(A | B) & (C | D)'.
|
||||
Type 'C & D' is not assignable to type 'A | B'.
|
||||
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 'B & D'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
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'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(34,1): error TS2322: Type 'C | D' is not assignable to type '(A | B) & (C | D)'.
|
||||
Type 'C' is not assignable to type '(A | B) & (C | D)'.
|
||||
Type 'C' is not assignable to type 'A | 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 & D'.
|
||||
Type 'C' is not assignable to type 'B'.
|
||||
Property 'b' is missing in type 'C'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(35,1): error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'A & B'.
|
||||
Type '(A | B) & (C | D)' is not assignable to type 'A'.
|
||||
Property 'a' is missing in type '(A | B) & (C | D)'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'C & D'.
|
||||
Type '(A | B) & (C | D)' is not assignable to type 'C'.
|
||||
Property 'c' is missing in type '(A | B) & (C | D)'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(35,1): error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'A & B'.
|
||||
Type 'A & C' is not assignable to type 'A & B'.
|
||||
Type 'A & C' is not assignable to type 'B'.
|
||||
Property 'b' is missing in type 'A & C'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'C & D'.
|
||||
Type 'A & C' is not assignable to type 'C & D'.
|
||||
Type 'A & C' is not assignable to type 'D'.
|
||||
Property 'd' is missing in type 'A & C'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts (14 errors) ====
|
||||
@ -127,38 +128,39 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): e
|
||||
|
||||
y = anb;
|
||||
~
|
||||
!!! error TS2322: Type 'A & B' is not assignable to type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type 'A & B' is not assignable to type 'C | D'.
|
||||
!!! 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'.
|
||||
y = aob;
|
||||
~
|
||||
!!! error TS2322: Type 'A | B' is not assignable to type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'C | D'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'D'.
|
||||
!!! error TS2322: Property 'd' is missing in type 'A'.
|
||||
!!! error TS2322: Type 'A | B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B & D'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
y = cnd;
|
||||
~
|
||||
!!! error TS2322: Type 'C & D' is not assignable to type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type 'C & D' is not assignable to type 'A | B'.
|
||||
!!! 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'.
|
||||
y = cod;
|
||||
~
|
||||
!!! error TS2322: Type 'C | D' is not assignable to type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type 'C' is not assignable to type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'A | B'.
|
||||
!!! error TS2322: Type 'C | D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
|
||||
!!! error TS2322: Type 'C' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'B & D'.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'B'.
|
||||
!!! error TS2322: Property 'b' is missing in type 'C'.
|
||||
anb = y;
|
||||
~~~
|
||||
!!! error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'A & B'.
|
||||
!!! error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'A'.
|
||||
!!! error TS2322: Property 'a' is missing in type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'A & B'.
|
||||
!!! error TS2322: Type 'A & C' is not assignable to type 'A & B'.
|
||||
!!! error TS2322: Type 'A & C' is not assignable to type 'B'.
|
||||
!!! error TS2322: Property 'b' is missing in type 'A & C'.
|
||||
aob = y; // Ok
|
||||
cnd = y;
|
||||
~~~
|
||||
!!! error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'C & D'.
|
||||
!!! error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'C'.
|
||||
!!! error TS2322: Property 'c' is missing in type '(A | B) & (C | D)'.
|
||||
!!! error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'C & D'.
|
||||
!!! error TS2322: Type 'A & C' is not assignable to type 'C & D'.
|
||||
!!! error TS2322: Type 'A & C' is not assignable to type 'D'.
|
||||
!!! error TS2322: Property 'd' is missing in type 'A & C'.
|
||||
cod = y; // Ok
|
||||
|
||||
79
tests/baselines/reference/intersectionTypeNormalization.js
Normal file
79
tests/baselines/reference/intersectionTypeNormalization.js
Normal file
@ -0,0 +1,79 @@
|
||||
//// [intersectionTypeNormalization.ts]
|
||||
interface A { a: string }
|
||||
interface B { b: string }
|
||||
interface C { c: string }
|
||||
interface D { d: string }
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type X1 = (A | B) & (C | D);
|
||||
type X2 = A & (C | D) | B & (C | D)
|
||||
type X3 = A & C | A & D | B & C | B & D;
|
||||
|
||||
var x: X1;
|
||||
var x: X2;
|
||||
var x: X3;
|
||||
|
||||
interface X { x: string }
|
||||
interface Y { y: string }
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Y1 = (A | X & Y) & (C | D);
|
||||
type Y2 = A & (C | D) | X & Y & (C | D)
|
||||
type Y3 = A & C | A & D | X & Y & C | X & Y & D;
|
||||
|
||||
var y: Y1;
|
||||
var y: Y2;
|
||||
var y: Y3;
|
||||
|
||||
interface M { m: string }
|
||||
interface N { n: string }
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Z1 = (A | X & (M | N)) & (C | D);
|
||||
type Z2 = A & (C | D) | X & (M | N) & (C | D)
|
||||
type Z3 = A & C | A & D | X & (M | N) & C | X & (M | N) & D;
|
||||
type Z4 = A & C | A & D | X & M & C | X & N & C | X & M & D | X & N & D;
|
||||
|
||||
var z: Z1;
|
||||
var z: Z2;
|
||||
var z: Z3;
|
||||
var z: Z4;
|
||||
|
||||
// Repro from #9919
|
||||
|
||||
type ToString = {
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
type BoxedValue = { kind: 'int', num: number }
|
||||
| { kind: 'string', str: string }
|
||||
|
||||
type IntersectionFail = BoxedValue & ToString
|
||||
|
||||
type IntersectionInline = { kind: 'int', num: number } & ToString
|
||||
| { kind: 'string', str: string } & ToString
|
||||
|
||||
function getValueAsString(value: IntersectionFail): string {
|
||||
if (value.kind === 'int') {
|
||||
return '' + value.num;
|
||||
}
|
||||
return value.str;
|
||||
}
|
||||
|
||||
//// [intersectionTypeNormalization.js]
|
||||
var x;
|
||||
var x;
|
||||
var x;
|
||||
var y;
|
||||
var y;
|
||||
var y;
|
||||
var z;
|
||||
var z;
|
||||
var z;
|
||||
var z;
|
||||
function getValueAsString(value) {
|
||||
if (value.kind === 'int') {
|
||||
return '' + value.num;
|
||||
}
|
||||
return value.str;
|
||||
}
|
||||
242
tests/baselines/reference/intersectionTypeNormalization.symbols
Normal file
242
tests/baselines/reference/intersectionTypeNormalization.symbols
Normal file
@ -0,0 +1,242 @@
|
||||
=== tests/cases/compiler/intersectionTypeNormalization.ts ===
|
||||
interface A { a: string }
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>a : Symbol(A.a, Decl(intersectionTypeNormalization.ts, 0, 13))
|
||||
|
||||
interface B { b: string }
|
||||
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 0, 25))
|
||||
>b : Symbol(B.b, Decl(intersectionTypeNormalization.ts, 1, 13))
|
||||
|
||||
interface C { c: string }
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>c : Symbol(C.c, Decl(intersectionTypeNormalization.ts, 2, 13))
|
||||
|
||||
interface D { d: string }
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>d : Symbol(D.d, Decl(intersectionTypeNormalization.ts, 3, 13))
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type X1 = (A | B) & (C | D);
|
||||
>X1 : Symbol(X1, Decl(intersectionTypeNormalization.ts, 3, 25))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 0, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
type X2 = A & (C | D) | B & (C | D)
|
||||
>X2 : Symbol(X2, Decl(intersectionTypeNormalization.ts, 6, 28))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 0, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
type X3 = A & C | A & D | B & C | B & D;
|
||||
>X3 : Symbol(X3, Decl(intersectionTypeNormalization.ts, 7, 35))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 0, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 0, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
var x: X1;
|
||||
>x : Symbol(x, Decl(intersectionTypeNormalization.ts, 10, 3), Decl(intersectionTypeNormalization.ts, 11, 3), Decl(intersectionTypeNormalization.ts, 12, 3))
|
||||
>X1 : Symbol(X1, Decl(intersectionTypeNormalization.ts, 3, 25))
|
||||
|
||||
var x: X2;
|
||||
>x : Symbol(x, Decl(intersectionTypeNormalization.ts, 10, 3), Decl(intersectionTypeNormalization.ts, 11, 3), Decl(intersectionTypeNormalization.ts, 12, 3))
|
||||
>X2 : Symbol(X2, Decl(intersectionTypeNormalization.ts, 6, 28))
|
||||
|
||||
var x: X3;
|
||||
>x : Symbol(x, Decl(intersectionTypeNormalization.ts, 10, 3), Decl(intersectionTypeNormalization.ts, 11, 3), Decl(intersectionTypeNormalization.ts, 12, 3))
|
||||
>X3 : Symbol(X3, Decl(intersectionTypeNormalization.ts, 7, 35))
|
||||
|
||||
interface X { x: string }
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>x : Symbol(X.x, Decl(intersectionTypeNormalization.ts, 14, 13))
|
||||
|
||||
interface Y { y: string }
|
||||
>Y : Symbol(Y, Decl(intersectionTypeNormalization.ts, 14, 25))
|
||||
>y : Symbol(Y.y, Decl(intersectionTypeNormalization.ts, 15, 13))
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Y1 = (A | X & Y) & (C | D);
|
||||
>Y1 : Symbol(Y1, Decl(intersectionTypeNormalization.ts, 15, 25))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>Y : Symbol(Y, Decl(intersectionTypeNormalization.ts, 14, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
type Y2 = A & (C | D) | X & Y & (C | D)
|
||||
>Y2 : Symbol(Y2, Decl(intersectionTypeNormalization.ts, 18, 32))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>Y : Symbol(Y, Decl(intersectionTypeNormalization.ts, 14, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
type Y3 = A & C | A & D | X & Y & C | X & Y & D;
|
||||
>Y3 : Symbol(Y3, Decl(intersectionTypeNormalization.ts, 19, 39))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>Y : Symbol(Y, Decl(intersectionTypeNormalization.ts, 14, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>Y : Symbol(Y, Decl(intersectionTypeNormalization.ts, 14, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
var y: Y1;
|
||||
>y : Symbol(y, Decl(intersectionTypeNormalization.ts, 22, 3), Decl(intersectionTypeNormalization.ts, 23, 3), Decl(intersectionTypeNormalization.ts, 24, 3))
|
||||
>Y1 : Symbol(Y1, Decl(intersectionTypeNormalization.ts, 15, 25))
|
||||
|
||||
var y: Y2;
|
||||
>y : Symbol(y, Decl(intersectionTypeNormalization.ts, 22, 3), Decl(intersectionTypeNormalization.ts, 23, 3), Decl(intersectionTypeNormalization.ts, 24, 3))
|
||||
>Y2 : Symbol(Y2, Decl(intersectionTypeNormalization.ts, 18, 32))
|
||||
|
||||
var y: Y3;
|
||||
>y : Symbol(y, Decl(intersectionTypeNormalization.ts, 22, 3), Decl(intersectionTypeNormalization.ts, 23, 3), Decl(intersectionTypeNormalization.ts, 24, 3))
|
||||
>Y3 : Symbol(Y3, Decl(intersectionTypeNormalization.ts, 19, 39))
|
||||
|
||||
interface M { m: string }
|
||||
>M : Symbol(M, Decl(intersectionTypeNormalization.ts, 24, 10))
|
||||
>m : Symbol(M.m, Decl(intersectionTypeNormalization.ts, 26, 13))
|
||||
|
||||
interface N { n: string }
|
||||
>N : Symbol(N, Decl(intersectionTypeNormalization.ts, 26, 25))
|
||||
>n : Symbol(N.n, Decl(intersectionTypeNormalization.ts, 27, 13))
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Z1 = (A | X & (M | N)) & (C | D);
|
||||
>Z1 : Symbol(Z1, Decl(intersectionTypeNormalization.ts, 27, 25))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>M : Symbol(M, Decl(intersectionTypeNormalization.ts, 24, 10))
|
||||
>N : Symbol(N, Decl(intersectionTypeNormalization.ts, 26, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
type Z2 = A & (C | D) | X & (M | N) & (C | D)
|
||||
>Z2 : Symbol(Z2, Decl(intersectionTypeNormalization.ts, 30, 38))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>M : Symbol(M, Decl(intersectionTypeNormalization.ts, 24, 10))
|
||||
>N : Symbol(N, Decl(intersectionTypeNormalization.ts, 26, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
type Z3 = A & C | A & D | X & (M | N) & C | X & (M | N) & D;
|
||||
>Z3 : Symbol(Z3, Decl(intersectionTypeNormalization.ts, 31, 45))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>M : Symbol(M, Decl(intersectionTypeNormalization.ts, 24, 10))
|
||||
>N : Symbol(N, Decl(intersectionTypeNormalization.ts, 26, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>M : Symbol(M, Decl(intersectionTypeNormalization.ts, 24, 10))
|
||||
>N : Symbol(N, Decl(intersectionTypeNormalization.ts, 26, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
type Z4 = A & C | A & D | X & M & C | X & N & C | X & M & D | X & N & D;
|
||||
>Z4 : Symbol(Z4, Decl(intersectionTypeNormalization.ts, 32, 60))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>M : Symbol(M, Decl(intersectionTypeNormalization.ts, 24, 10))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>N : Symbol(N, Decl(intersectionTypeNormalization.ts, 26, 25))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 1, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>M : Symbol(M, Decl(intersectionTypeNormalization.ts, 24, 10))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
>X : Symbol(X, Decl(intersectionTypeNormalization.ts, 12, 10))
|
||||
>N : Symbol(N, Decl(intersectionTypeNormalization.ts, 26, 25))
|
||||
>D : Symbol(D, Decl(intersectionTypeNormalization.ts, 2, 25))
|
||||
|
||||
var z: Z1;
|
||||
>z : Symbol(z, Decl(intersectionTypeNormalization.ts, 35, 3), Decl(intersectionTypeNormalization.ts, 36, 3), Decl(intersectionTypeNormalization.ts, 37, 3), Decl(intersectionTypeNormalization.ts, 38, 3))
|
||||
>Z1 : Symbol(Z1, Decl(intersectionTypeNormalization.ts, 27, 25))
|
||||
|
||||
var z: Z2;
|
||||
>z : Symbol(z, Decl(intersectionTypeNormalization.ts, 35, 3), Decl(intersectionTypeNormalization.ts, 36, 3), Decl(intersectionTypeNormalization.ts, 37, 3), Decl(intersectionTypeNormalization.ts, 38, 3))
|
||||
>Z2 : Symbol(Z2, Decl(intersectionTypeNormalization.ts, 30, 38))
|
||||
|
||||
var z: Z3;
|
||||
>z : Symbol(z, Decl(intersectionTypeNormalization.ts, 35, 3), Decl(intersectionTypeNormalization.ts, 36, 3), Decl(intersectionTypeNormalization.ts, 37, 3), Decl(intersectionTypeNormalization.ts, 38, 3))
|
||||
>Z3 : Symbol(Z3, Decl(intersectionTypeNormalization.ts, 31, 45))
|
||||
|
||||
var z: Z4;
|
||||
>z : Symbol(z, Decl(intersectionTypeNormalization.ts, 35, 3), Decl(intersectionTypeNormalization.ts, 36, 3), Decl(intersectionTypeNormalization.ts, 37, 3), Decl(intersectionTypeNormalization.ts, 38, 3))
|
||||
>Z4 : Symbol(Z4, Decl(intersectionTypeNormalization.ts, 32, 60))
|
||||
|
||||
// Repro from #9919
|
||||
|
||||
type ToString = {
|
||||
>ToString : Symbol(ToString, Decl(intersectionTypeNormalization.ts, 38, 10))
|
||||
|
||||
toString(): string;
|
||||
>toString : Symbol(toString, Decl(intersectionTypeNormalization.ts, 42, 17))
|
||||
}
|
||||
|
||||
type BoxedValue = { kind: 'int', num: number }
|
||||
>BoxedValue : Symbol(BoxedValue, Decl(intersectionTypeNormalization.ts, 44, 1))
|
||||
>kind : Symbol(kind, Decl(intersectionTypeNormalization.ts, 46, 19))
|
||||
>num : Symbol(num, Decl(intersectionTypeNormalization.ts, 46, 32))
|
||||
|
||||
| { kind: 'string', str: string }
|
||||
>kind : Symbol(kind, Decl(intersectionTypeNormalization.ts, 47, 19))
|
||||
>str : Symbol(str, Decl(intersectionTypeNormalization.ts, 47, 35))
|
||||
|
||||
type IntersectionFail = BoxedValue & ToString
|
||||
>IntersectionFail : Symbol(IntersectionFail, Decl(intersectionTypeNormalization.ts, 47, 49))
|
||||
>BoxedValue : Symbol(BoxedValue, Decl(intersectionTypeNormalization.ts, 44, 1))
|
||||
>ToString : Symbol(ToString, Decl(intersectionTypeNormalization.ts, 38, 10))
|
||||
|
||||
type IntersectionInline = { kind: 'int', num: number } & ToString
|
||||
>IntersectionInline : Symbol(IntersectionInline, Decl(intersectionTypeNormalization.ts, 49, 45))
|
||||
>kind : Symbol(kind, Decl(intersectionTypeNormalization.ts, 51, 27))
|
||||
>num : Symbol(num, Decl(intersectionTypeNormalization.ts, 51, 40))
|
||||
>ToString : Symbol(ToString, Decl(intersectionTypeNormalization.ts, 38, 10))
|
||||
|
||||
| { kind: 'string', str: string } & ToString
|
||||
>kind : Symbol(kind, Decl(intersectionTypeNormalization.ts, 52, 27))
|
||||
>str : Symbol(str, Decl(intersectionTypeNormalization.ts, 52, 43))
|
||||
>ToString : Symbol(ToString, Decl(intersectionTypeNormalization.ts, 38, 10))
|
||||
|
||||
function getValueAsString(value: IntersectionFail): string {
|
||||
>getValueAsString : Symbol(getValueAsString, Decl(intersectionTypeNormalization.ts, 52, 68))
|
||||
>value : Symbol(value, Decl(intersectionTypeNormalization.ts, 54, 26))
|
||||
>IntersectionFail : Symbol(IntersectionFail, Decl(intersectionTypeNormalization.ts, 47, 49))
|
||||
|
||||
if (value.kind === 'int') {
|
||||
>value.kind : Symbol(kind, Decl(intersectionTypeNormalization.ts, 46, 19), Decl(intersectionTypeNormalization.ts, 47, 19))
|
||||
>value : Symbol(value, Decl(intersectionTypeNormalization.ts, 54, 26))
|
||||
>kind : Symbol(kind, Decl(intersectionTypeNormalization.ts, 46, 19), Decl(intersectionTypeNormalization.ts, 47, 19))
|
||||
|
||||
return '' + value.num;
|
||||
>value.num : Symbol(num, Decl(intersectionTypeNormalization.ts, 46, 32))
|
||||
>value : Symbol(value, Decl(intersectionTypeNormalization.ts, 54, 26))
|
||||
>num : Symbol(num, Decl(intersectionTypeNormalization.ts, 46, 32))
|
||||
}
|
||||
return value.str;
|
||||
>value.str : Symbol(str, Decl(intersectionTypeNormalization.ts, 47, 35))
|
||||
>value : Symbol(value, Decl(intersectionTypeNormalization.ts, 54, 26))
|
||||
>str : Symbol(str, Decl(intersectionTypeNormalization.ts, 47, 35))
|
||||
}
|
||||
246
tests/baselines/reference/intersectionTypeNormalization.types
Normal file
246
tests/baselines/reference/intersectionTypeNormalization.types
Normal file
@ -0,0 +1,246 @@
|
||||
=== tests/cases/compiler/intersectionTypeNormalization.ts ===
|
||||
interface A { a: string }
|
||||
>A : A
|
||||
>a : string
|
||||
|
||||
interface B { b: string }
|
||||
>B : B
|
||||
>b : string
|
||||
|
||||
interface C { c: string }
|
||||
>C : C
|
||||
>c : string
|
||||
|
||||
interface D { d: string }
|
||||
>D : D
|
||||
>d : string
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type X1 = (A | B) & (C | D);
|
||||
>X1 : X1
|
||||
>A : A
|
||||
>B : B
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
type X2 = A & (C | D) | B & (C | D)
|
||||
>X2 : X1
|
||||
>A : A
|
||||
>C : C
|
||||
>D : D
|
||||
>B : B
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
type X3 = A & C | A & D | B & C | B & D;
|
||||
>X3 : X1
|
||||
>A : A
|
||||
>C : C
|
||||
>A : A
|
||||
>D : D
|
||||
>B : B
|
||||
>C : C
|
||||
>B : B
|
||||
>D : D
|
||||
|
||||
var x: X1;
|
||||
>x : X1
|
||||
>X1 : X1
|
||||
|
||||
var x: X2;
|
||||
>x : X1
|
||||
>X2 : X1
|
||||
|
||||
var x: X3;
|
||||
>x : X1
|
||||
>X3 : X1
|
||||
|
||||
interface X { x: string }
|
||||
>X : X
|
||||
>x : string
|
||||
|
||||
interface Y { y: string }
|
||||
>Y : Y
|
||||
>y : string
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Y1 = (A | X & Y) & (C | D);
|
||||
>Y1 : Y1
|
||||
>A : A
|
||||
>X : X
|
||||
>Y : Y
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
type Y2 = A & (C | D) | X & Y & (C | D)
|
||||
>Y2 : Y1
|
||||
>A : A
|
||||
>C : C
|
||||
>D : D
|
||||
>X : X
|
||||
>Y : Y
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
type Y3 = A & C | A & D | X & Y & C | X & Y & D;
|
||||
>Y3 : Y1
|
||||
>A : A
|
||||
>C : C
|
||||
>A : A
|
||||
>D : D
|
||||
>X : X
|
||||
>Y : Y
|
||||
>C : C
|
||||
>X : X
|
||||
>Y : Y
|
||||
>D : D
|
||||
|
||||
var y: Y1;
|
||||
>y : Y1
|
||||
>Y1 : Y1
|
||||
|
||||
var y: Y2;
|
||||
>y : Y1
|
||||
>Y2 : Y1
|
||||
|
||||
var y: Y3;
|
||||
>y : Y1
|
||||
>Y3 : Y1
|
||||
|
||||
interface M { m: string }
|
||||
>M : M
|
||||
>m : string
|
||||
|
||||
interface N { n: string }
|
||||
>N : N
|
||||
>n : string
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Z1 = (A | X & (M | N)) & (C | D);
|
||||
>Z1 : Z1
|
||||
>A : A
|
||||
>X : X
|
||||
>M : M
|
||||
>N : N
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
type Z2 = A & (C | D) | X & (M | N) & (C | D)
|
||||
>Z2 : Z1
|
||||
>A : A
|
||||
>C : C
|
||||
>D : D
|
||||
>X : X
|
||||
>M : M
|
||||
>N : N
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
type Z3 = A & C | A & D | X & (M | N) & C | X & (M | N) & D;
|
||||
>Z3 : Z1
|
||||
>A : A
|
||||
>C : C
|
||||
>A : A
|
||||
>D : D
|
||||
>X : X
|
||||
>M : M
|
||||
>N : N
|
||||
>C : C
|
||||
>X : X
|
||||
>M : M
|
||||
>N : N
|
||||
>D : D
|
||||
|
||||
type Z4 = A & C | A & D | X & M & C | X & N & C | X & M & D | X & N & D;
|
||||
>Z4 : Z1
|
||||
>A : A
|
||||
>C : C
|
||||
>A : A
|
||||
>D : D
|
||||
>X : X
|
||||
>M : M
|
||||
>C : C
|
||||
>X : X
|
||||
>N : N
|
||||
>C : C
|
||||
>X : X
|
||||
>M : M
|
||||
>D : D
|
||||
>X : X
|
||||
>N : N
|
||||
>D : D
|
||||
|
||||
var z: Z1;
|
||||
>z : Z1
|
||||
>Z1 : Z1
|
||||
|
||||
var z: Z2;
|
||||
>z : Z1
|
||||
>Z2 : Z1
|
||||
|
||||
var z: Z3;
|
||||
>z : Z1
|
||||
>Z3 : Z1
|
||||
|
||||
var z: Z4;
|
||||
>z : Z1
|
||||
>Z4 : Z1
|
||||
|
||||
// Repro from #9919
|
||||
|
||||
type ToString = {
|
||||
>ToString : { toString(): string; }
|
||||
|
||||
toString(): string;
|
||||
>toString : () => string
|
||||
}
|
||||
|
||||
type BoxedValue = { kind: 'int', num: number }
|
||||
>BoxedValue : BoxedValue
|
||||
>kind : "int"
|
||||
>num : number
|
||||
|
||||
| { kind: 'string', str: string }
|
||||
>kind : "string"
|
||||
>str : string
|
||||
|
||||
type IntersectionFail = BoxedValue & ToString
|
||||
>IntersectionFail : IntersectionFail
|
||||
>BoxedValue : BoxedValue
|
||||
>ToString : { toString(): string; }
|
||||
|
||||
type IntersectionInline = { kind: 'int', num: number } & ToString
|
||||
>IntersectionInline : IntersectionInline
|
||||
>kind : "int"
|
||||
>num : number
|
||||
>ToString : { toString(): string; }
|
||||
|
||||
| { kind: 'string', str: string } & ToString
|
||||
>kind : "string"
|
||||
>str : string
|
||||
>ToString : { toString(): string; }
|
||||
|
||||
function getValueAsString(value: IntersectionFail): string {
|
||||
>getValueAsString : (value: IntersectionFail) => string
|
||||
>value : IntersectionFail
|
||||
>IntersectionFail : IntersectionFail
|
||||
|
||||
if (value.kind === 'int') {
|
||||
>value.kind === 'int' : boolean
|
||||
>value.kind : "int" | "string"
|
||||
>value : IntersectionFail
|
||||
>kind : "int" | "string"
|
||||
>'int' : "int"
|
||||
|
||||
return '' + value.num;
|
||||
>'' + value.num : string
|
||||
>'' : ""
|
||||
>value.num : number
|
||||
>value : { kind: "int"; num: number; } & { toString(): string; }
|
||||
>num : number
|
||||
}
|
||||
return value.str;
|
||||
>value.str : string
|
||||
>value : { kind: "string"; str: string; } & { toString(): string; }
|
||||
>str : string
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(19,10): error TS2678: Type 'number & boolean' is not comparable to type 'string & number'.
|
||||
Type 'number & boolean' is not comparable to type 'string'.
|
||||
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(19,10): error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'.
|
||||
Type 'number & false' is not comparable to type 'string & number'.
|
||||
Type 'number & false' is not comparable to type 'string'.
|
||||
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(23,10): error TS2678: Type 'boolean' is not comparable to type 'string & number'.
|
||||
|
||||
|
||||
@ -24,8 +25,9 @@ tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithInterse
|
||||
// Overlap in constituents
|
||||
case numAndBool:
|
||||
~~~~~~~~~~
|
||||
!!! error TS2678: Type 'number & boolean' is not comparable to type 'string & number'.
|
||||
!!! error TS2678: Type 'number & boolean' is not comparable to type 'string'.
|
||||
!!! error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'.
|
||||
!!! error TS2678: Type 'number & false' is not comparable to type 'string & number'.
|
||||
!!! error TS2678: Type 'number & false' is not comparable to type 'string'.
|
||||
break;
|
||||
|
||||
// No relation
|
||||
|
||||
@ -25,7 +25,7 @@ if (!(result instanceof RegExp)) {
|
||||
|
||||
} else if (!result.global) {
|
||||
>!result.global : boolean
|
||||
>result.global : string & boolean
|
||||
>result.global : (string & true) | (string & false)
|
||||
>result : I & RegExp
|
||||
>global : string & boolean
|
||||
>global : (string & true) | (string & false)
|
||||
}
|
||||
|
||||
60
tests/cases/compiler/intersectionTypeNormalization.ts
Normal file
60
tests/cases/compiler/intersectionTypeNormalization.ts
Normal file
@ -0,0 +1,60 @@
|
||||
interface A { a: string }
|
||||
interface B { b: string }
|
||||
interface C { c: string }
|
||||
interface D { d: string }
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type X1 = (A | B) & (C | D);
|
||||
type X2 = A & (C | D) | B & (C | D)
|
||||
type X3 = A & C | A & D | B & C | B & D;
|
||||
|
||||
var x: X1;
|
||||
var x: X2;
|
||||
var x: X3;
|
||||
|
||||
interface X { x: string }
|
||||
interface Y { y: string }
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Y1 = (A | X & Y) & (C | D);
|
||||
type Y2 = A & (C | D) | X & Y & (C | D)
|
||||
type Y3 = A & C | A & D | X & Y & C | X & Y & D;
|
||||
|
||||
var y: Y1;
|
||||
var y: Y2;
|
||||
var y: Y3;
|
||||
|
||||
interface M { m: string }
|
||||
interface N { n: string }
|
||||
|
||||
// Identical ways of writing the same type
|
||||
type Z1 = (A | X & (M | N)) & (C | D);
|
||||
type Z2 = A & (C | D) | X & (M | N) & (C | D)
|
||||
type Z3 = A & C | A & D | X & (M | N) & C | X & (M | N) & D;
|
||||
type Z4 = A & C | A & D | X & M & C | X & N & C | X & M & D | X & N & D;
|
||||
|
||||
var z: Z1;
|
||||
var z: Z2;
|
||||
var z: Z3;
|
||||
var z: Z4;
|
||||
|
||||
// Repro from #9919
|
||||
|
||||
type ToString = {
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
type BoxedValue = { kind: 'int', num: number }
|
||||
| { kind: 'string', str: string }
|
||||
|
||||
type IntersectionFail = BoxedValue & ToString
|
||||
|
||||
type IntersectionInline = { kind: 'int', num: number } & ToString
|
||||
| { kind: 'string', str: string } & ToString
|
||||
|
||||
function getValueAsString(value: IntersectionFail): string {
|
||||
if (value.kind === 'int') {
|
||||
return '' + value.num;
|
||||
}
|
||||
return value.str;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user