From d5710349a29041290d2d2ce9e875e03c18fd79ae Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 24 Jun 2015 17:53:43 -0700 Subject: [PATCH] Adding tests --- .../intersectionAndUnionTypes.errors.txt | 162 ++++++++++++++++++ .../reference/intersectionAndUnionTypes.js | 72 ++++++++ .../reference/intersectionTypeEquivalence.js | 31 ++++ .../intersectionTypeEquivalence.symbols | 63 +++++++ .../intersectionTypeEquivalence.types | 63 +++++++ .../intersectionTypeInference.errors.txt | 27 +++ .../reference/intersectionTypeInference.js | 28 +++ .../reference/intersectionTypeMembers.js | 44 +++++ .../reference/intersectionTypeMembers.symbols | 100 +++++++++++ .../reference/intersectionTypeMembers.types | 116 +++++++++++++ .../recursiveIntersectionTypes.errors.txt | 32 ++++ .../reference/recursiveIntersectionTypes.js | 31 ++++ .../intersection/intersectionAndUnionTypes.ts | 38 ++++ .../intersectionTypeEquivalence.ts | 16 ++ .../intersection/intersectionTypeInference.ts | 13 ++ .../intersection/intersectionTypeMembers.ts | 27 +++ .../recursiveIntersectionTypes.ts | 19 ++ 17 files changed, 882 insertions(+) create mode 100644 tests/baselines/reference/intersectionAndUnionTypes.errors.txt create mode 100644 tests/baselines/reference/intersectionAndUnionTypes.js create mode 100644 tests/baselines/reference/intersectionTypeEquivalence.js create mode 100644 tests/baselines/reference/intersectionTypeEquivalence.symbols create mode 100644 tests/baselines/reference/intersectionTypeEquivalence.types create mode 100644 tests/baselines/reference/intersectionTypeInference.errors.txt create mode 100644 tests/baselines/reference/intersectionTypeInference.js create mode 100644 tests/baselines/reference/intersectionTypeMembers.js create mode 100644 tests/baselines/reference/intersectionTypeMembers.symbols create mode 100644 tests/baselines/reference/intersectionTypeMembers.types create mode 100644 tests/baselines/reference/recursiveIntersectionTypes.errors.txt create mode 100644 tests/baselines/reference/recursiveIntersectionTypes.js create mode 100644 tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts create mode 100644 tests/cases/conformance/types/intersection/intersectionTypeEquivalence.ts create mode 100644 tests/cases/conformance/types/intersection/intersectionTypeInference.ts create mode 100644 tests/cases/conformance/types/intersection/intersectionTypeMembers.ts create mode 100644 tests/cases/conformance/types/intersection/recursiveIntersectionTypes.ts diff --git a/tests/baselines/reference/intersectionAndUnionTypes.errors.txt b/tests/baselines/reference/intersectionAndUnionTypes.errors.txt new file mode 100644 index 00000000000..4f26cc63ba3 --- /dev/null +++ b/tests/baselines/reference/intersectionAndUnionTypes.errors.txt @@ -0,0 +1,162 @@ +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(19,1): error TS2322: Type 'A' is not assignable to type 'A & B'. + Type 'A' is not assignable to type 'B'. +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(20,1): error TS2322: Type 'B' is not assignable to type 'A & B'. + Type 'B' is not assignable to type 'A'. + Property 'a' is missing in type 'B'. +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(23,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 'C'. +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(25,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 'C & D'. + Type 'C' is not assignable to type 'D'. +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(26,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A & B'. + Type 'C & D' is not assignable to type 'A & B'. + Type 'C & D' is not assignable to type 'A'. + Type 'D' is not assignable to type 'A'. +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(27,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A | B'. + Type 'C & D' is not assignable to type 'A | B'. + Type 'C & D' is not assignable to type 'B'. + Type 'D' is not assignable to type 'B'. +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(28,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C & D'. + Type 'A & B' is not assignable to type 'C & D'. + Type 'A & B' is not assignable to type 'C'. + Type 'B' is not assignable to type 'C'. +tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(29,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C | D'. + Type 'A & B' is not assignable to type 'C | D'. + Type 'A & B' is not assignable to type 'D'. + Type 'B' is not assignable to type 'D'. +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'. + Type 'A & B' is not assignable to type 'D'. + Type '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'. +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'. + Type 'C & D' is not assignable to type 'B'. + Type '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'. + Type 'C' is not assignable to type 'B'. +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'. + Type 'C | D' is not assignable to type 'A'. + Type 'C' is not assignable to type 'A'. +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'. + Type 'C | D' is not assignable to type 'C'. + Type 'D' is not assignable to type 'C'. + + +==== tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts (14 errors) ==== + interface A { a: string } + interface B { b: string } + interface C { c: string } + interface D { d: string } + + var a: A; + var b: B; + var c: C; + var d: D; + var anb: A & B; + var aob: A | B; + var cnd: C & D; + var cod: C | D; + var x: A & B | C & D; + var y: (A | B) & (C | D); + + a = anb; // Ok + b = anb; // Ok + anb = a; + ~~~ +!!! error TS2322: Type 'A' is not assignable to type 'A & B'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. + anb = b; + ~~~ +!!! error TS2322: Type 'B' is not assignable to type 'A & B'. +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'a' is missing in type 'B'. + + x = anb; // Ok + x = 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 'C'. + x = cnd; // Ok + x = 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 'C & D'. +!!! error TS2322: Type 'C' is not assignable to type 'D'. + anb = x; + ~~~ +!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A & B'. +!!! error TS2322: Type 'C & D' is not assignable to type 'A & B'. +!!! error TS2322: Type 'C & D' is not assignable to type 'A'. +!!! error TS2322: Type 'D' is not assignable to type 'A'. + aob = x; + ~~~ +!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A | B'. +!!! error TS2322: Type 'C & D' is not assignable to type 'A | B'. +!!! error TS2322: Type 'C & D' is not assignable to type 'B'. +!!! error TS2322: Type 'D' is not assignable to type 'B'. + cnd = x; + ~~~ +!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C & D'. +!!! error TS2322: Type 'A & B' is not assignable to type 'C & D'. +!!! error TS2322: Type 'A & B' is not assignable to type 'C'. +!!! error TS2322: Type 'B' is not assignable to type 'C'. + cod = x; + ~~~ +!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C | D'. +!!! error TS2322: Type 'A & B' is not assignable to type 'C | D'. +!!! error TS2322: Type 'A & B' is not assignable to type 'D'. +!!! error TS2322: Type 'B' is not assignable to type 'D'. + + 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 'D'. +!!! error TS2322: Type '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'. + 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 'B'. +!!! error TS2322: Type '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' is not assignable to type 'B'. + 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: Type 'C | D' is not assignable to type 'A'. +!!! error TS2322: Type 'C' is not assignable to type 'A'. + 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: Type 'C | D' is not assignable to type 'C'. +!!! error TS2322: Type 'D' is not assignable to type 'C'. + cod = y; // Ok + \ No newline at end of file diff --git a/tests/baselines/reference/intersectionAndUnionTypes.js b/tests/baselines/reference/intersectionAndUnionTypes.js new file mode 100644 index 00000000000..ec0adaab8b8 --- /dev/null +++ b/tests/baselines/reference/intersectionAndUnionTypes.js @@ -0,0 +1,72 @@ +//// [intersectionAndUnionTypes.ts] +interface A { a: string } +interface B { b: string } +interface C { c: string } +interface D { d: string } + +var a: A; +var b: B; +var c: C; +var d: D; +var anb: A & B; +var aob: A | B; +var cnd: C & D; +var cod: C | D; +var x: A & B | C & D; +var y: (A | B) & (C | D); + +a = anb; // Ok +b = anb; // Ok +anb = a; +anb = b; + +x = anb; // Ok +x = aob; +x = cnd; // Ok +x = cod; +anb = x; +aob = x; +cnd = x; +cod = x; + +y = anb; +y = aob; +y = cnd; +y = cod; +anb = y; +aob = y; // Ok +cnd = y; +cod = y; // Ok + + +//// [intersectionAndUnionTypes.js] +var a; +var b; +var c; +var d; +var anb; +var aob; +var cnd; +var cod; +var x; +var y; +a = anb; // Ok +b = anb; // Ok +anb = a; +anb = b; +x = anb; // Ok +x = aob; +x = cnd; // Ok +x = cod; +anb = x; +aob = x; +cnd = x; +cod = x; +y = anb; +y = aob; +y = cnd; +y = cod; +anb = y; +aob = y; // Ok +cnd = y; +cod = y; // Ok diff --git a/tests/baselines/reference/intersectionTypeEquivalence.js b/tests/baselines/reference/intersectionTypeEquivalence.js new file mode 100644 index 00000000000..be04bfe7947 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeEquivalence.js @@ -0,0 +1,31 @@ +//// [intersectionTypeEquivalence.ts] +interface A { a: string } +interface B { b: string } +interface C { c: string } + +// A & B is equivalent to B & A. +var y: A & B; +var y : B & A; + +// AB & C is equivalent to A & BC, where AB is A & B and BC is B & C. +var z : A & B & C; +var z : (A & B) & C; +var z : A & (B & C); +var ab : A & B; +var bc : B & C; +var z1: typeof ab & C; +var z1: A & typeof bc; + + +//// [intersectionTypeEquivalence.js] +// A & B is equivalent to B & A. +var y; +var y; +// AB & C is equivalent to A & BC, where AB is A & B and BC is B & C. +var z; +var z; +var z; +var ab; +var bc; +var z1; +var z1; diff --git a/tests/baselines/reference/intersectionTypeEquivalence.symbols b/tests/baselines/reference/intersectionTypeEquivalence.symbols new file mode 100644 index 00000000000..2bec452c44e --- /dev/null +++ b/tests/baselines/reference/intersectionTypeEquivalence.symbols @@ -0,0 +1,63 @@ +=== tests/cases/conformance/types/intersection/intersectionTypeEquivalence.ts === +interface A { a: string } +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) +>a : Symbol(a, Decl(intersectionTypeEquivalence.ts, 0, 13)) + +interface B { b: string } +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) +>b : Symbol(b, Decl(intersectionTypeEquivalence.ts, 1, 13)) + +interface C { c: string } +>C : Symbol(C, Decl(intersectionTypeEquivalence.ts, 1, 25)) +>c : Symbol(c, Decl(intersectionTypeEquivalence.ts, 2, 13)) + +// A & B is equivalent to B & A. +var y: A & B; +>y : Symbol(y, Decl(intersectionTypeEquivalence.ts, 5, 3), Decl(intersectionTypeEquivalence.ts, 6, 3)) +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) + +var y : B & A; +>y : Symbol(y, Decl(intersectionTypeEquivalence.ts, 5, 3), Decl(intersectionTypeEquivalence.ts, 6, 3)) +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) + +// AB & C is equivalent to A & BC, where AB is A & B and BC is B & C. +var z : A & B & C; +>z : Symbol(z, Decl(intersectionTypeEquivalence.ts, 9, 3), Decl(intersectionTypeEquivalence.ts, 10, 3), Decl(intersectionTypeEquivalence.ts, 11, 3)) +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) +>C : Symbol(C, Decl(intersectionTypeEquivalence.ts, 1, 25)) + +var z : (A & B) & C; +>z : Symbol(z, Decl(intersectionTypeEquivalence.ts, 9, 3), Decl(intersectionTypeEquivalence.ts, 10, 3), Decl(intersectionTypeEquivalence.ts, 11, 3)) +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) +>C : Symbol(C, Decl(intersectionTypeEquivalence.ts, 1, 25)) + +var z : A & (B & C); +>z : Symbol(z, Decl(intersectionTypeEquivalence.ts, 9, 3), Decl(intersectionTypeEquivalence.ts, 10, 3), Decl(intersectionTypeEquivalence.ts, 11, 3)) +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) +>C : Symbol(C, Decl(intersectionTypeEquivalence.ts, 1, 25)) + +var ab : A & B; +>ab : Symbol(ab, Decl(intersectionTypeEquivalence.ts, 12, 3)) +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) + +var bc : B & C; +>bc : Symbol(bc, Decl(intersectionTypeEquivalence.ts, 13, 3)) +>B : Symbol(B, Decl(intersectionTypeEquivalence.ts, 0, 25)) +>C : Symbol(C, Decl(intersectionTypeEquivalence.ts, 1, 25)) + +var z1: typeof ab & C; +>z1 : Symbol(z1, Decl(intersectionTypeEquivalence.ts, 14, 3), Decl(intersectionTypeEquivalence.ts, 15, 3)) +>ab : Symbol(ab, Decl(intersectionTypeEquivalence.ts, 12, 3)) +>C : Symbol(C, Decl(intersectionTypeEquivalence.ts, 1, 25)) + +var z1: A & typeof bc; +>z1 : Symbol(z1, Decl(intersectionTypeEquivalence.ts, 14, 3), Decl(intersectionTypeEquivalence.ts, 15, 3)) +>A : Symbol(A, Decl(intersectionTypeEquivalence.ts, 0, 0)) +>bc : Symbol(bc, Decl(intersectionTypeEquivalence.ts, 13, 3)) + diff --git a/tests/baselines/reference/intersectionTypeEquivalence.types b/tests/baselines/reference/intersectionTypeEquivalence.types new file mode 100644 index 00000000000..25e175275d7 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeEquivalence.types @@ -0,0 +1,63 @@ +=== tests/cases/conformance/types/intersection/intersectionTypeEquivalence.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 + +// A & B is equivalent to B & A. +var y: A & B; +>y : A & B +>A : A +>B : B + +var y : B & A; +>y : A & B +>B : B +>A : A + +// AB & C is equivalent to A & BC, where AB is A & B and BC is B & C. +var z : A & B & C; +>z : A & B & C +>A : A +>B : B +>C : C + +var z : (A & B) & C; +>z : A & B & C +>A : A +>B : B +>C : C + +var z : A & (B & C); +>z : A & B & C +>A : A +>B : B +>C : C + +var ab : A & B; +>ab : A & B +>A : A +>B : B + +var bc : B & C; +>bc : B & C +>B : B +>C : C + +var z1: typeof ab & C; +>z1 : A & B & C +>ab : A & B +>C : C + +var z1: A & typeof bc; +>z1 : A & B & C +>A : A +>bc : B & C + diff --git a/tests/baselines/reference/intersectionTypeInference.errors.txt b/tests/baselines/reference/intersectionTypeInference.errors.txt new file mode 100644 index 00000000000..33c24e111dc --- /dev/null +++ b/tests/baselines/reference/intersectionTypeInference.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/types/intersection/intersectionTypeInference.ts(6,5): error TS2322: Type 'T' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'U'. +tests/cases/conformance/types/intersection/intersectionTypeInference.ts(7,5): error TS2322: Type 'U' is not assignable to type 'T & U'. + Type 'U' is not assignable to type 'T'. + + +==== tests/cases/conformance/types/intersection/intersectionTypeInference.ts (2 errors) ==== + + function extend(obj1: T, obj2: U): T & U { + var result: T & U; + obj1 = result; + obj2 = result; + result = obj1; // Error + ~~~~~~ +!!! error TS2322: Type 'T' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. + result = obj2; // Error + ~~~~~~ +!!! error TS2322: Type 'U' is not assignable to type 'T & U'. +!!! error TS2322: Type 'U' is not assignable to type 'T'. + return result; + } + + var x = extend({ a: "hello" }, { b: 42 }); + var s = x.a; + var n = x.b; + \ No newline at end of file diff --git a/tests/baselines/reference/intersectionTypeInference.js b/tests/baselines/reference/intersectionTypeInference.js new file mode 100644 index 00000000000..0b95879a6c0 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeInference.js @@ -0,0 +1,28 @@ +//// [intersectionTypeInference.ts] + +function extend(obj1: T, obj2: U): T & U { + var result: T & U; + obj1 = result; + obj2 = result; + result = obj1; // Error + result = obj2; // Error + return result; +} + +var x = extend({ a: "hello" }, { b: 42 }); +var s = x.a; +var n = x.b; + + +//// [intersectionTypeInference.js] +function extend(obj1, obj2) { + var result; + obj1 = result; + obj2 = result; + result = obj1; // Error + result = obj2; // Error + return result; +} +var x = extend({ a: "hello" }, { b: 42 }); +var s = x.a; +var n = x.b; diff --git a/tests/baselines/reference/intersectionTypeMembers.js b/tests/baselines/reference/intersectionTypeMembers.js new file mode 100644 index 00000000000..9c1cd75d601 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeMembers.js @@ -0,0 +1,44 @@ +//// [intersectionTypeMembers.ts] +// An intersection type has those members that are present in any of its constituent types, +// with types that are intersections of the respective members in the constituent types + +interface A { a: string } +interface B { b: string } +interface C { c: string } + +var abc: A & B & C; +abc.a = "hello"; +abc.b = "hello"; +abc.c = "hello"; + +interface X { x: A } +interface Y { x: B } +interface Z { x: C } + +var xyz: X & Y & Z; +xyz.x.a = "hello"; +xyz.x.b = "hello"; +xyz.x.c = "hello"; + +type F1 = (x: string) => string; +type F2 = (x: number) => number; + +var f: F1 & F2; +var s = f("hello"); +var n = f(42); + + +//// [intersectionTypeMembers.js] +// An intersection type has those members that are present in any of its constituent types, +// with types that are intersections of the respective members in the constituent types +var abc; +abc.a = "hello"; +abc.b = "hello"; +abc.c = "hello"; +var xyz; +xyz.x.a = "hello"; +xyz.x.b = "hello"; +xyz.x.c = "hello"; +var f; +var s = f("hello"); +var n = f(42); diff --git a/tests/baselines/reference/intersectionTypeMembers.symbols b/tests/baselines/reference/intersectionTypeMembers.symbols new file mode 100644 index 00000000000..ebec69b4ebe --- /dev/null +++ b/tests/baselines/reference/intersectionTypeMembers.symbols @@ -0,0 +1,100 @@ +=== tests/cases/conformance/types/intersection/intersectionTypeMembers.ts === +// An intersection type has those members that are present in any of its constituent types, +// with types that are intersections of the respective members in the constituent types + +interface A { a: string } +>A : Symbol(A, Decl(intersectionTypeMembers.ts, 0, 0)) +>a : Symbol(a, Decl(intersectionTypeMembers.ts, 3, 13)) + +interface B { b: string } +>B : Symbol(B, Decl(intersectionTypeMembers.ts, 3, 25)) +>b : Symbol(b, Decl(intersectionTypeMembers.ts, 4, 13)) + +interface C { c: string } +>C : Symbol(C, Decl(intersectionTypeMembers.ts, 4, 25)) +>c : Symbol(c, Decl(intersectionTypeMembers.ts, 5, 13)) + +var abc: A & B & C; +>abc : Symbol(abc, Decl(intersectionTypeMembers.ts, 7, 3)) +>A : Symbol(A, Decl(intersectionTypeMembers.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionTypeMembers.ts, 3, 25)) +>C : Symbol(C, Decl(intersectionTypeMembers.ts, 4, 25)) + +abc.a = "hello"; +>abc.a : Symbol(A.a, Decl(intersectionTypeMembers.ts, 3, 13)) +>abc : Symbol(abc, Decl(intersectionTypeMembers.ts, 7, 3)) +>a : Symbol(A.a, Decl(intersectionTypeMembers.ts, 3, 13)) + +abc.b = "hello"; +>abc.b : Symbol(B.b, Decl(intersectionTypeMembers.ts, 4, 13)) +>abc : Symbol(abc, Decl(intersectionTypeMembers.ts, 7, 3)) +>b : Symbol(B.b, Decl(intersectionTypeMembers.ts, 4, 13)) + +abc.c = "hello"; +>abc.c : Symbol(C.c, Decl(intersectionTypeMembers.ts, 5, 13)) +>abc : Symbol(abc, Decl(intersectionTypeMembers.ts, 7, 3)) +>c : Symbol(C.c, Decl(intersectionTypeMembers.ts, 5, 13)) + +interface X { x: A } +>X : Symbol(X, Decl(intersectionTypeMembers.ts, 10, 16)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 12, 13)) +>A : Symbol(A, Decl(intersectionTypeMembers.ts, 0, 0)) + +interface Y { x: B } +>Y : Symbol(Y, Decl(intersectionTypeMembers.ts, 12, 20)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 13, 13)) +>B : Symbol(B, Decl(intersectionTypeMembers.ts, 3, 25)) + +interface Z { x: C } +>Z : Symbol(Z, Decl(intersectionTypeMembers.ts, 13, 20)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 14, 13)) +>C : Symbol(C, Decl(intersectionTypeMembers.ts, 4, 25)) + +var xyz: X & Y & Z; +>xyz : Symbol(xyz, Decl(intersectionTypeMembers.ts, 16, 3)) +>X : Symbol(X, Decl(intersectionTypeMembers.ts, 10, 16)) +>Y : Symbol(Y, Decl(intersectionTypeMembers.ts, 12, 20)) +>Z : Symbol(Z, Decl(intersectionTypeMembers.ts, 13, 20)) + +xyz.x.a = "hello"; +>xyz.x.a : Symbol(A.a, Decl(intersectionTypeMembers.ts, 3, 13)) +>xyz.x : Symbol(x, Decl(intersectionTypeMembers.ts, 12, 13), Decl(intersectionTypeMembers.ts, 13, 13), Decl(intersectionTypeMembers.ts, 14, 13)) +>xyz : Symbol(xyz, Decl(intersectionTypeMembers.ts, 16, 3)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 12, 13), Decl(intersectionTypeMembers.ts, 13, 13), Decl(intersectionTypeMembers.ts, 14, 13)) +>a : Symbol(A.a, Decl(intersectionTypeMembers.ts, 3, 13)) + +xyz.x.b = "hello"; +>xyz.x.b : Symbol(B.b, Decl(intersectionTypeMembers.ts, 4, 13)) +>xyz.x : Symbol(x, Decl(intersectionTypeMembers.ts, 12, 13), Decl(intersectionTypeMembers.ts, 13, 13), Decl(intersectionTypeMembers.ts, 14, 13)) +>xyz : Symbol(xyz, Decl(intersectionTypeMembers.ts, 16, 3)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 12, 13), Decl(intersectionTypeMembers.ts, 13, 13), Decl(intersectionTypeMembers.ts, 14, 13)) +>b : Symbol(B.b, Decl(intersectionTypeMembers.ts, 4, 13)) + +xyz.x.c = "hello"; +>xyz.x.c : Symbol(C.c, Decl(intersectionTypeMembers.ts, 5, 13)) +>xyz.x : Symbol(x, Decl(intersectionTypeMembers.ts, 12, 13), Decl(intersectionTypeMembers.ts, 13, 13), Decl(intersectionTypeMembers.ts, 14, 13)) +>xyz : Symbol(xyz, Decl(intersectionTypeMembers.ts, 16, 3)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 12, 13), Decl(intersectionTypeMembers.ts, 13, 13), Decl(intersectionTypeMembers.ts, 14, 13)) +>c : Symbol(C.c, Decl(intersectionTypeMembers.ts, 5, 13)) + +type F1 = (x: string) => string; +>F1 : Symbol(F1, Decl(intersectionTypeMembers.ts, 19, 18)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 21, 11)) + +type F2 = (x: number) => number; +>F2 : Symbol(F2, Decl(intersectionTypeMembers.ts, 21, 32)) +>x : Symbol(x, Decl(intersectionTypeMembers.ts, 22, 11)) + +var f: F1 & F2; +>f : Symbol(f, Decl(intersectionTypeMembers.ts, 24, 3)) +>F1 : Symbol(F1, Decl(intersectionTypeMembers.ts, 19, 18)) +>F2 : Symbol(F2, Decl(intersectionTypeMembers.ts, 21, 32)) + +var s = f("hello"); +>s : Symbol(s, Decl(intersectionTypeMembers.ts, 25, 3)) +>f : Symbol(f, Decl(intersectionTypeMembers.ts, 24, 3)) + +var n = f(42); +>n : Symbol(n, Decl(intersectionTypeMembers.ts, 26, 3)) +>f : Symbol(f, Decl(intersectionTypeMembers.ts, 24, 3)) + diff --git a/tests/baselines/reference/intersectionTypeMembers.types b/tests/baselines/reference/intersectionTypeMembers.types new file mode 100644 index 00000000000..a97a54c7a81 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeMembers.types @@ -0,0 +1,116 @@ +=== tests/cases/conformance/types/intersection/intersectionTypeMembers.ts === +// An intersection type has those members that are present in any of its constituent types, +// with types that are intersections of the respective members in the constituent types + +interface A { a: string } +>A : A +>a : string + +interface B { b: string } +>B : B +>b : string + +interface C { c: string } +>C : C +>c : string + +var abc: A & B & C; +>abc : A & B & C +>A : A +>B : B +>C : C + +abc.a = "hello"; +>abc.a = "hello" : string +>abc.a : string +>abc : A & B & C +>a : string +>"hello" : string + +abc.b = "hello"; +>abc.b = "hello" : string +>abc.b : string +>abc : A & B & C +>b : string +>"hello" : string + +abc.c = "hello"; +>abc.c = "hello" : string +>abc.c : string +>abc : A & B & C +>c : string +>"hello" : string + +interface X { x: A } +>X : X +>x : A +>A : A + +interface Y { x: B } +>Y : Y +>x : B +>B : B + +interface Z { x: C } +>Z : Z +>x : C +>C : C + +var xyz: X & Y & Z; +>xyz : X & Y & Z +>X : X +>Y : Y +>Z : Z + +xyz.x.a = "hello"; +>xyz.x.a = "hello" : string +>xyz.x.a : string +>xyz.x : A & B & C +>xyz : X & Y & Z +>x : A & B & C +>a : string +>"hello" : string + +xyz.x.b = "hello"; +>xyz.x.b = "hello" : string +>xyz.x.b : string +>xyz.x : A & B & C +>xyz : X & Y & Z +>x : A & B & C +>b : string +>"hello" : string + +xyz.x.c = "hello"; +>xyz.x.c = "hello" : string +>xyz.x.c : string +>xyz.x : A & B & C +>xyz : X & Y & Z +>x : A & B & C +>c : string +>"hello" : string + +type F1 = (x: string) => string; +>F1 : (x: string) => string +>x : string + +type F2 = (x: number) => number; +>F2 : (x: number) => number +>x : number + +var f: F1 & F2; +>f : ((x: string) => string) & ((x: number) => number) +>F1 : (x: string) => string +>F2 : (x: number) => number + +var s = f("hello"); +>s : string +>f("hello") : string +>f : ((x: string) => string) & ((x: number) => number) +>"hello" : string + +var n = f(42); +>n : number +>f(42) : number +>f : ((x: string) => string) & ((x: number) => number) +>42 : number + diff --git a/tests/baselines/reference/recursiveIntersectionTypes.errors.txt b/tests/baselines/reference/recursiveIntersectionTypes.errors.txt new file mode 100644 index 00000000000..bac97470e55 --- /dev/null +++ b/tests/baselines/reference/recursiveIntersectionTypes.errors.txt @@ -0,0 +1,32 @@ +tests/cases/conformance/types/intersection/recursiveIntersectionTypes.ts(19,1): error TS2322: Type 'Entity & { next: Entity & any; }' is not assignable to type 'Product & { next: Product & any; }'. + Type 'Entity & { next: Entity & any; }' is not assignable to type 'Product'. + Type '{ next: Entity & any; }' is not assignable to type 'Product'. + Property 'price' is missing in type '{ next: Entity & any; }'. + + +==== tests/cases/conformance/types/intersection/recursiveIntersectionTypes.ts (1 errors) ==== + type LinkedList = T & { next: LinkedList }; + + interface Entity { + name: string; + } + + interface Product extends Entity { + price: number; + } + + var entityList: LinkedList; + var s = entityList.name; + var s = entityList.next.name; + var s = entityList.next.next.name; + var s = entityList.next.next.next.name; + + var productList: LinkedList; + entityList = productList; + productList = entityList; // Error + ~~~~~~~~~~~ +!!! error TS2322: Type 'Entity & { next: Entity & any; }' is not assignable to type 'Product & { next: Product & any; }'. +!!! error TS2322: Type 'Entity & { next: Entity & any; }' is not assignable to type 'Product'. +!!! error TS2322: Type '{ next: Entity & any; }' is not assignable to type 'Product'. +!!! error TS2322: Property 'price' is missing in type '{ next: Entity & any; }'. + \ No newline at end of file diff --git a/tests/baselines/reference/recursiveIntersectionTypes.js b/tests/baselines/reference/recursiveIntersectionTypes.js new file mode 100644 index 00000000000..88b7e6f831b --- /dev/null +++ b/tests/baselines/reference/recursiveIntersectionTypes.js @@ -0,0 +1,31 @@ +//// [recursiveIntersectionTypes.ts] +type LinkedList = T & { next: LinkedList }; + +interface Entity { + name: string; +} + +interface Product extends Entity { + price: number; +} + +var entityList: LinkedList; +var s = entityList.name; +var s = entityList.next.name; +var s = entityList.next.next.name; +var s = entityList.next.next.next.name; + +var productList: LinkedList; +entityList = productList; +productList = entityList; // Error + + +//// [recursiveIntersectionTypes.js] +var entityList; +var s = entityList.name; +var s = entityList.next.name; +var s = entityList.next.next.name; +var s = entityList.next.next.next.name; +var productList; +entityList = productList; +productList = entityList; // Error diff --git a/tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts b/tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts new file mode 100644 index 00000000000..e6bd671c6b2 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts @@ -0,0 +1,38 @@ +interface A { a: string } +interface B { b: string } +interface C { c: string } +interface D { d: string } + +var a: A; +var b: B; +var c: C; +var d: D; +var anb: A & B; +var aob: A | B; +var cnd: C & D; +var cod: C | D; +var x: A & B | C & D; +var y: (A | B) & (C | D); + +a = anb; // Ok +b = anb; // Ok +anb = a; +anb = b; + +x = anb; // Ok +x = aob; +x = cnd; // Ok +x = cod; +anb = x; +aob = x; +cnd = x; +cod = x; + +y = anb; +y = aob; +y = cnd; +y = cod; +anb = y; +aob = y; // Ok +cnd = y; +cod = y; // Ok diff --git a/tests/cases/conformance/types/intersection/intersectionTypeEquivalence.ts b/tests/cases/conformance/types/intersection/intersectionTypeEquivalence.ts new file mode 100644 index 00000000000..fce399eff94 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionTypeEquivalence.ts @@ -0,0 +1,16 @@ +interface A { a: string } +interface B { b: string } +interface C { c: string } + +// A & B is equivalent to B & A. +var y: A & B; +var y : B & A; + +// AB & C is equivalent to A & BC, where AB is A & B and BC is B & C. +var z : A & B & C; +var z : (A & B) & C; +var z : A & (B & C); +var ab : A & B; +var bc : B & C; +var z1: typeof ab & C; +var z1: A & typeof bc; diff --git a/tests/cases/conformance/types/intersection/intersectionTypeInference.ts b/tests/cases/conformance/types/intersection/intersectionTypeInference.ts new file mode 100644 index 00000000000..3126ce09448 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionTypeInference.ts @@ -0,0 +1,13 @@ + +function extend(obj1: T, obj2: U): T & U { + var result: T & U; + obj1 = result; + obj2 = result; + result = obj1; // Error + result = obj2; // Error + return result; +} + +var x = extend({ a: "hello" }, { b: 42 }); +var s = x.a; +var n = x.b; diff --git a/tests/cases/conformance/types/intersection/intersectionTypeMembers.ts b/tests/cases/conformance/types/intersection/intersectionTypeMembers.ts new file mode 100644 index 00000000000..a8c92647f47 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionTypeMembers.ts @@ -0,0 +1,27 @@ +// An intersection type has those members that are present in any of its constituent types, +// with types that are intersections of the respective members in the constituent types + +interface A { a: string } +interface B { b: string } +interface C { c: string } + +var abc: A & B & C; +abc.a = "hello"; +abc.b = "hello"; +abc.c = "hello"; + +interface X { x: A } +interface Y { x: B } +interface Z { x: C } + +var xyz: X & Y & Z; +xyz.x.a = "hello"; +xyz.x.b = "hello"; +xyz.x.c = "hello"; + +type F1 = (x: string) => string; +type F2 = (x: number) => number; + +var f: F1 & F2; +var s = f("hello"); +var n = f(42); diff --git a/tests/cases/conformance/types/intersection/recursiveIntersectionTypes.ts b/tests/cases/conformance/types/intersection/recursiveIntersectionTypes.ts new file mode 100644 index 00000000000..d741d30ac1f --- /dev/null +++ b/tests/cases/conformance/types/intersection/recursiveIntersectionTypes.ts @@ -0,0 +1,19 @@ +type LinkedList = T & { next: LinkedList }; + +interface Entity { + name: string; +} + +interface Product extends Entity { + price: number; +} + +var entityList: LinkedList; +var s = entityList.name; +var s = entityList.next.name; +var s = entityList.next.next.name; +var s = entityList.next.next.next.name; + +var productList: LinkedList; +entityList = productList; +productList = entityList; // Error