From e90f5e063e155d926970e5e770bf560df4f12e98 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 10:05:48 -0700 Subject: [PATCH] More tests of enum assignability 1. Numeric literal <-> enum literal assignability 2. Computed enum <-> union enum assignability 3. Also rebaseline error reporting of existing enum cases. --- .../enumAssignmentCompat3.errors.txt | 24 ++++----- .../enumAssignmentCompat5.errors.txt | 33 ++++++++++++ .../reference/enumAssignmentCompat5.js | 50 +++++++++++++++++++ ...eralAssignableToEnumInsideUnion.errors.txt | 37 ++++++++++++++ .../enumLiteralAssignableToEnumInsideUnion.js | 40 ++++++++++++++- ...LiteralAssignableToEnumInsideUnion.symbols | 35 ++++++++++++- ...umLiteralAssignableToEnumInsideUnion.types | 39 +++++++++++++++ tests/cases/compiler/enumAssignmentCompat5.ts | 23 +++++++++ .../enumLiteralAssignableToEnumInsideUnion.ts | 18 ++++++- 9 files changed, 280 insertions(+), 19 deletions(-) create mode 100644 tests/baselines/reference/enumAssignmentCompat5.errors.txt create mode 100644 tests/baselines/reference/enumAssignmentCompat5.js create mode 100644 tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt create mode 100644 tests/cases/compiler/enumAssignmentCompat5.ts diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index bfdaef96775..41fa7a94fca 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -1,16 +1,13 @@ -tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2324: Property 'd' is missing in type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(70,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(70,1): error TS2324: Property 'd' is missing in type 'First.E'. tests/cases/compiler/enumAssignmentCompat3.ts(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'. -tests/cases/compiler/enumAssignmentCompat3.ts(75,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. - Property 'c' is missing in type 'Ab.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(75,1): error TS2324: Property 'c' is missing in type 'Ab.E'. tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. - Property 'a' is missing in type 'Cd.E'. tests/cases/compiler/enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'. tests/cases/compiler/enumAssignmentCompat3.ts(82,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. tests/cases/compiler/enumAssignmentCompat3.ts(83,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. - Property 'd' is missing in type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2324: Property 'd' is missing in type 'First.E'. ==== tests/cases/compiler/enumAssignmentCompat3.ts (9 errors) ==== @@ -83,12 +80,12 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged. abc = secondAbc; // ok abc = secondAbcd; // missing 'd' ~~~ -!!! error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. -!!! error TS2322: Property 'd' is missing in type 'First.E'. +!!! error TS2324: Property 'd' is missing in type 'First.E'. abc = secondAb; // ok abc = secondCd; // missing 'd' ~~~ -!!! error TS2324: Property 'd' is missing in type 'First.E'. +!!! error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. +!!! error TS2322: Property 'd' is missing in type 'First.E'. abc = nope; // nope! ~~~ !!! error TS2322: Type 'Nope' is not assignable to type 'E'. @@ -97,12 +94,10 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged. secondAbcd = abc; // ok secondAb = abc; // missing 'c' ~~~~~~~~ -!!! error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. -!!! error TS2322: Property 'c' is missing in type 'Ab.E'. +!!! error TS2324: Property 'c' is missing in type 'Ab.E'. secondCd = abc; // missing 'a' and 'b' ~~~~~~~~ !!! error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. -!!! error TS2322: Property 'a' is missing in type 'Cd.E'. nope = abc; // nope! ~~~~ !!! error TS2322: Type 'E' is not assignable to type 'Nope'. @@ -120,8 +115,7 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged. // merged enums compare all their members abc = merged; // missing 'd' ~~~ -!!! error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. -!!! error TS2322: Property 'd' is missing in type 'First.E'. +!!! error TS2324: Property 'd' is missing in type 'First.E'. merged = abc; // ok abc = merged2; // ok merged2 = abc; // ok \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat5.errors.txt b/tests/baselines/reference/enumAssignmentCompat5.errors.txt new file mode 100644 index 00000000000..98c0aaccfad --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat5.errors.txt @@ -0,0 +1,33 @@ +tests/cases/compiler/enumAssignmentCompat5.ts(14,1): error TS2322: Type '2' is not assignable to type 'E.A'. +tests/cases/compiler/enumAssignmentCompat5.ts(20,9): error TS2535: Enum type 'Computed' has members with initializers that are not literals. + + +==== tests/cases/compiler/enumAssignmentCompat5.ts (2 errors) ==== + enum E { + A, B, C + } + enum Computed { + A = 1 << 1, + B = 1 << 2, + C = 1 << 3, + } + let n: number; + let e: E = n; // ok because it's too inconvenient otherwise + e = 0; // ok, in range + e = 4; // ok, out of range, but allowed computed enums don't have all members + let a: E.A = 0; // ok, A === 0 + a = 2; // error, 2 !== 0 + ~ +!!! error TS2322: Type '2' is not assignable to type 'E.A'. + a = n; // ok + + let c: Computed = n; // ok + c = n; // ok + c = 4; // ok + let ca: Computed.A = 1; // error, Computed.A isn't a literal type because Computed has no enum literals + ~~~~~~~~~~ +!!! error TS2535: Enum type 'Computed' has members with initializers that are not literals. + + + + \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat5.js b/tests/baselines/reference/enumAssignmentCompat5.js new file mode 100644 index 00000000000..a7c96929f08 --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat5.js @@ -0,0 +1,50 @@ +//// [enumAssignmentCompat5.ts] +enum E { + A, B, C +} +enum Computed { + A = 1 << 1, + B = 1 << 2, + C = 1 << 3, +} +let n: number; +let e: E = n; // ok because it's too inconvenient otherwise +e = 0; // ok, in range +e = 4; // ok, out of range, but allowed computed enums don't have all members +let a: E.A = 0; // ok, A === 0 +a = 2; // error, 2 !== 0 +a = n; // ok + +let c: Computed = n; // ok +c = n; // ok +c = 4; // ok +let ca: Computed.A = 1; // error, Computed.A isn't a literal type because Computed has no enum literals + + + + + +//// [enumAssignmentCompat5.js] +var E; +(function (E) { + E[E["A"] = 0] = "A"; + E[E["B"] = 1] = "B"; + E[E["C"] = 2] = "C"; +})(E || (E = {})); +var Computed; +(function (Computed) { + Computed[Computed["A"] = 2] = "A"; + Computed[Computed["B"] = 4] = "B"; + Computed[Computed["C"] = 8] = "C"; +})(Computed || (Computed = {})); +var n; +var e = n; // ok because it's too inconvenient otherwise +e = 0; // ok, in range +e = 4; // ok, out of range, but allowed computed enums don't have all members +var a = 0; // ok, A === 0 +a = 2; // error, 2 !== 0 +a = n; // ok +var c = n; // ok +c = n; // ok +c = 4; // ok +var ca = 1; // error, Computed.A isn't a literal type because Computed has no enum literals diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt new file mode 100644 index 00000000000..37bdc99a922 --- /dev/null +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt @@ -0,0 +1,37 @@ +tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(25,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.B'. +tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(26,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'. + + +==== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts (2 errors) ==== + module X { + export enum Foo { + A, B + } + } + module Y { + export enum Foo { + A, B + } + } + module Z { + export enum Foo { + A = 1 << 1, + B = 1 << 2, + } + } + module Ka { + export enum Foo { + A = 1 << 10, + B = 1 << 11, + } + } + const e1: X.Foo | boolean = Z.Foo.A; // ok + const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // ok, X.Foo is equivalent to X.Foo.A | X.Foo.B + const e3: X.Foo.B | boolean = Z.Foo.A; // not legal + ~~ +!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.B'. + const e4: X.Foo.A | boolean = Z.Foo.A; // not legal either because Z.Foo is computed and Z.Foo.A is not necessarily assignable to X.Foo.A + ~~ +!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'. + const e5: Ka.Foo | boolean = Z.Foo.A; // ok + \ No newline at end of file diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js index 607269e06e3..1665e729719 100644 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js @@ -9,7 +9,23 @@ module Y { A, B } } -const y: X.Foo | boolean = Y.Foo.A; +module Z { + export enum Foo { + A = 1 << 1, + B = 1 << 2, + } +} +module Ka { + export enum Foo { + A = 1 << 10, + B = 1 << 11, + } +} +const e1: X.Foo | boolean = Z.Foo.A; // ok +const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // ok, X.Foo is equivalent to X.Foo.A | X.Foo.B +const e3: X.Foo.B | boolean = Z.Foo.A; // not legal +const e4: X.Foo.A | boolean = Z.Foo.A; // not legal either because Z.Foo is computed and Z.Foo.A is not necessarily assignable to X.Foo.A +const e5: Ka.Foo | boolean = Z.Foo.A; // ok //// [enumLiteralAssignableToEnumInsideUnion.js] @@ -29,4 +45,24 @@ var Y; })(Y.Foo || (Y.Foo = {})); var Foo = Y.Foo; })(Y || (Y = {})); -var y = Y.Foo.A; +var Z; +(function (Z) { + (function (Foo) { + Foo[Foo["A"] = 2] = "A"; + Foo[Foo["B"] = 4] = "B"; + })(Z.Foo || (Z.Foo = {})); + var Foo = Z.Foo; +})(Z || (Z = {})); +var Ka; +(function (Ka) { + (function (Foo) { + Foo[Foo["A"] = 1024] = "A"; + Foo[Foo["B"] = 2048] = "B"; + })(Ka.Foo || (Ka.Foo = {})); + var Foo = Ka.Foo; +})(Ka || (Ka = {})); +var e1 = Z.Foo.A; // ok +var e2 = Z.Foo.A; // ok, X.Foo is equivalent to X.Foo.A | X.Foo.B +var e3 = Z.Foo.A; // not legal +var e4 = Z.Foo.A; // not legal either because Z.Foo is computed and Z.Foo.A is not necessarily assignable to X.Foo.A +var e5 = Z.Foo.A; // ok diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols index 979bd516682..8df8e21b386 100644 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols @@ -21,8 +21,21 @@ module Y { >B : Symbol(Foo.B, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 7, 10)) } } +module Z { +>Z : Symbol(Z, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 9, 1)) + + export enum Foo { +>Foo : Symbol(Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 10, 10)) + + A = 1 << 1, +>A : Symbol(Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 11, 21)) + + B = 1 << 2, +>B : Symbol(Foo.B, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 12, 19)) + } +} const y: X.Foo | boolean = Y.Foo.A; ->y : Symbol(y, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 10, 5)) +>y : Symbol(y, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 16, 5)) >X : Symbol(X, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 0)) >Foo : Symbol(X.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 10)) >Y.Foo.A : Symbol(Y.Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 6, 21)) @@ -31,3 +44,23 @@ const y: X.Foo | boolean = Y.Foo.A; >Foo : Symbol(Y.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 5, 10)) >A : Symbol(Y.Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 6, 21)) +const z: X.Foo | boolean = Z.Foo.A; +>z : Symbol(z, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 17, 5)) +>X : Symbol(X, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 0)) +>Foo : Symbol(X.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 10)) +>Z.Foo.A : Symbol(Z.Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 11, 21)) +>Z.Foo : Symbol(Z.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 10, 10)) +>Z : Symbol(Z, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 9, 1)) +>Foo : Symbol(Z.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 10, 10)) +>A : Symbol(Z.Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 11, 21)) + +const x: Z.Foo | boolean = X.Foo.A; +>x : Symbol(x, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 18, 5)) +>Z : Symbol(Z, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 9, 1)) +>Foo : Symbol(Z.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 10, 10)) +>X.Foo.A : Symbol(X.Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 1, 21)) +>X.Foo : Symbol(X.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 10)) +>X : Symbol(X, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 0)) +>Foo : Symbol(X.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 10)) +>A : Symbol(X.Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 1, 21)) + diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types index de57b5e92bc..5dbb98bcf9c 100644 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types @@ -21,6 +21,25 @@ module Y { >B : Foo } } +module Z { +>Z : typeof Z + + export enum Foo { +>Foo : Foo + + A = 1 << 1, +>A : Foo +>1 << 1 : number +>1 : number +>1 : number + + B = 1 << 2, +>B : Foo +>1 << 2 : number +>1 : number +>2 : number + } +} const y: X.Foo | boolean = Y.Foo.A; >y : boolean | X.Foo >X : any @@ -31,3 +50,23 @@ const y: X.Foo | boolean = Y.Foo.A; >Foo : typeof Y.Foo >A : Y.Foo +const z: X.Foo | boolean = Z.Foo.A; +>z : boolean | X.Foo +>X : any +>Foo : X.Foo +>Z.Foo.A : Z.Foo +>Z.Foo : typeof Z.Foo +>Z : typeof Z +>Foo : typeof Z.Foo +>A : Z.Foo + +const x: Z.Foo | boolean = X.Foo.A; +>x : boolean | Z.Foo +>Z : any +>Foo : Z.Foo +>X.Foo.A : X.Foo +>X.Foo : typeof X.Foo +>X : typeof X +>Foo : typeof X.Foo +>A : X.Foo + diff --git a/tests/cases/compiler/enumAssignmentCompat5.ts b/tests/cases/compiler/enumAssignmentCompat5.ts new file mode 100644 index 00000000000..c56db8b04f5 --- /dev/null +++ b/tests/cases/compiler/enumAssignmentCompat5.ts @@ -0,0 +1,23 @@ +enum E { + A, B, C +} +enum Computed { + A = 1 << 1, + B = 1 << 2, + C = 1 << 3, +} +let n: number; +let e: E = n; // ok because it's too inconvenient otherwise +e = 0; // ok, in range +e = 4; // ok, out of range, but allowed computed enums don't have all members +let a: E.A = 0; // ok, A === 0 +a = 2; // error, 2 !== 0 +a = n; // ok + +let c: Computed = n; // ok +c = n; // ok +c = 4; // ok +let ca: Computed.A = 1; // error, Computed.A isn't a literal type because Computed has no enum literals + + + diff --git a/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts b/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts index 0c10155e48d..c3029af0f42 100644 --- a/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts +++ b/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts @@ -8,4 +8,20 @@ module Y { A, B } } -const y: X.Foo | boolean = Y.Foo.A; +module Z { + export enum Foo { + A = 1 << 1, + B = 1 << 2, + } +} +module Ka { + export enum Foo { + A = 1 << 10, + B = 1 << 11, + } +} +const e1: X.Foo | boolean = Z.Foo.A; // ok +const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // ok, X.Foo is equivalent to X.Foo.A | X.Foo.B +const e3: X.Foo.B | boolean = Z.Foo.A; // not legal +const e4: X.Foo.A | boolean = Z.Foo.A; // not legal either because Z.Foo is computed and Z.Foo.A is not necessarily assignable to X.Foo.A +const e5: Ka.Foo | boolean = Z.Foo.A; // ok