From 3b40affeb76689fa1a1ce0c70cd123e387d29951 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 8 Sep 2016 11:16:45 -0700 Subject: [PATCH 01/14] Number is assignable to enum, even inside union Previously, numbers were not assignable to enums that were inside a union --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 565d01bf024..b14c6be383c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6235,6 +6235,9 @@ namespace ts { if (relation === assignableRelation || relation === comparableRelation) { if (source.flags & TypeFlags.Any) return true; if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && target.flags & TypeFlags.Enum) return true; + if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && + target.flags & TypeFlags.Union && + forEach((target as UnionType).types, t => t.flags & TypeFlags.EnumLike)) return true; if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.EnumLiteral && (source).text === (target).text) return true; } return false; From 1cd0093b72cb49f1768ac98e4af86240a7622c54 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 8 Sep 2016 11:21:40 -0700 Subject: [PATCH 02/14] Test that number is assignable to enum in a union --- .../reference/numberAssignableToEnumInsideUnion.js | 14 ++++++++++++++ .../numberAssignableToEnumInsideUnion.symbols | 14 ++++++++++++++ .../numberAssignableToEnumInsideUnion.types | 14 ++++++++++++++ .../compiler/numberAssignableToEnumInsideUnion.ts | 3 +++ 4 files changed, 45 insertions(+) create mode 100644 tests/baselines/reference/numberAssignableToEnumInsideUnion.js create mode 100644 tests/baselines/reference/numberAssignableToEnumInsideUnion.symbols create mode 100644 tests/baselines/reference/numberAssignableToEnumInsideUnion.types create mode 100644 tests/cases/compiler/numberAssignableToEnumInsideUnion.ts diff --git a/tests/baselines/reference/numberAssignableToEnumInsideUnion.js b/tests/baselines/reference/numberAssignableToEnumInsideUnion.js new file mode 100644 index 00000000000..584b395212d --- /dev/null +++ b/tests/baselines/reference/numberAssignableToEnumInsideUnion.js @@ -0,0 +1,14 @@ +//// [numberAssignableToEnumInsideUnion.ts] +enum E { A, B } +let n: number; +let z: E | boolean = n; + + +//// [numberAssignableToEnumInsideUnion.js] +var E; +(function (E) { + E[E["A"] = 0] = "A"; + E[E["B"] = 1] = "B"; +})(E || (E = {})); +var n; +var z = n; diff --git a/tests/baselines/reference/numberAssignableToEnumInsideUnion.symbols b/tests/baselines/reference/numberAssignableToEnumInsideUnion.symbols new file mode 100644 index 00000000000..4d815a99690 --- /dev/null +++ b/tests/baselines/reference/numberAssignableToEnumInsideUnion.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/numberAssignableToEnumInsideUnion.ts === +enum E { A, B } +>E : Symbol(E, Decl(numberAssignableToEnumInsideUnion.ts, 0, 0)) +>A : Symbol(E.A, Decl(numberAssignableToEnumInsideUnion.ts, 0, 8)) +>B : Symbol(E.B, Decl(numberAssignableToEnumInsideUnion.ts, 0, 11)) + +let n: number; +>n : Symbol(n, Decl(numberAssignableToEnumInsideUnion.ts, 1, 3)) + +let z: E | boolean = n; +>z : Symbol(z, Decl(numberAssignableToEnumInsideUnion.ts, 2, 3)) +>E : Symbol(E, Decl(numberAssignableToEnumInsideUnion.ts, 0, 0)) +>n : Symbol(n, Decl(numberAssignableToEnumInsideUnion.ts, 1, 3)) + diff --git a/tests/baselines/reference/numberAssignableToEnumInsideUnion.types b/tests/baselines/reference/numberAssignableToEnumInsideUnion.types new file mode 100644 index 00000000000..fd45ff17622 --- /dev/null +++ b/tests/baselines/reference/numberAssignableToEnumInsideUnion.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/numberAssignableToEnumInsideUnion.ts === +enum E { A, B } +>E : E +>A : E +>B : E + +let n: number; +>n : number + +let z: E | boolean = n; +>z : boolean | E +>E : E +>n : number + diff --git a/tests/cases/compiler/numberAssignableToEnumInsideUnion.ts b/tests/cases/compiler/numberAssignableToEnumInsideUnion.ts new file mode 100644 index 00000000000..fbefb5ac802 --- /dev/null +++ b/tests/cases/compiler/numberAssignableToEnumInsideUnion.ts @@ -0,0 +1,3 @@ +enum E { A, B } +let n: number; +let z: E | boolean = n; From 1bc61c77aa8950226fb74f9c14b79465da672d35 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 8 Sep 2016 14:41:35 -0700 Subject: [PATCH 03/14] Enum literal is assignable to enum, even inside union Previously, only number literals were assignable to enums inside unions. --- src/compiler/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b14c6be383c..ddb250255ee 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6238,7 +6238,9 @@ namespace ts { if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && target.flags & TypeFlags.Union && forEach((target as UnionType).types, t => t.flags & TypeFlags.EnumLike)) return true; - if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.EnumLiteral && (source).text === (target).text) return true; + if (source.flags & (TypeFlags.NumberLiteral | TypeFlags.EnumLiteral) && + target.flags & TypeFlags.EnumLiteral && + (source).text === (target).text) return true; } return false; } From 570433e5a0d66547ca00aac3f15e8a52cb9e03b6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 8 Sep 2016 14:43:17 -0700 Subject: [PATCH 04/14] Test that enum literal is assignable to an enum in a union --- .../enumLiteralAssignableToEnumInsideUnion.js | 32 ++++++++++++++++++ ...LiteralAssignableToEnumInsideUnion.symbols | 33 +++++++++++++++++++ ...umLiteralAssignableToEnumInsideUnion.types | 33 +++++++++++++++++++ .../enumLiteralAssignableToEnumInsideUnion.ts | 11 +++++++ 4 files changed, 109 insertions(+) create mode 100644 tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js create mode 100644 tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols create mode 100644 tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types create mode 100644 tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js new file mode 100644 index 00000000000..607269e06e3 --- /dev/null +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js @@ -0,0 +1,32 @@ +//// [enumLiteralAssignableToEnumInsideUnion.ts] +module X { + export enum Foo { + A, B + } +} +module Y { + export enum Foo { + A, B + } +} +const y: X.Foo | boolean = Y.Foo.A; + + +//// [enumLiteralAssignableToEnumInsideUnion.js] +var X; +(function (X) { + (function (Foo) { + Foo[Foo["A"] = 0] = "A"; + Foo[Foo["B"] = 1] = "B"; + })(X.Foo || (X.Foo = {})); + var Foo = X.Foo; +})(X || (X = {})); +var Y; +(function (Y) { + (function (Foo) { + Foo[Foo["A"] = 0] = "A"; + Foo[Foo["B"] = 1] = "B"; + })(Y.Foo || (Y.Foo = {})); + var Foo = Y.Foo; +})(Y || (Y = {})); +var y = Y.Foo.A; diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols new file mode 100644 index 00000000000..979bd516682 --- /dev/null +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts === +module X { +>X : Symbol(X, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 0)) + + export enum Foo { +>Foo : Symbol(Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 10)) + + A, B +>A : Symbol(Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 1, 21)) +>B : Symbol(Foo.B, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 2, 10)) + } +} +module Y { +>Y : Symbol(Y, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 4, 1)) + + export enum Foo { +>Foo : Symbol(Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 5, 10)) + + A, B +>A : Symbol(Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 6, 21)) +>B : Symbol(Foo.B, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 7, 10)) + } +} +const y: X.Foo | boolean = Y.Foo.A; +>y : Symbol(y, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 10, 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)) +>Y.Foo : Symbol(Y.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 5, 10)) +>Y : Symbol(Y, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 4, 1)) +>Foo : Symbol(Y.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 5, 10)) +>A : Symbol(Y.Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 6, 21)) + diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types new file mode 100644 index 00000000000..de57b5e92bc --- /dev/null +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts === +module X { +>X : typeof X + + export enum Foo { +>Foo : Foo + + A, B +>A : Foo +>B : Foo + } +} +module Y { +>Y : typeof Y + + export enum Foo { +>Foo : Foo + + A, B +>A : Foo +>B : Foo + } +} +const y: X.Foo | boolean = Y.Foo.A; +>y : boolean | X.Foo +>X : any +>Foo : X.Foo +>Y.Foo.A : Y.Foo +>Y.Foo : typeof Y.Foo +>Y : typeof Y +>Foo : typeof Y.Foo +>A : Y.Foo + diff --git a/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts b/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts new file mode 100644 index 00000000000..0c10155e48d --- /dev/null +++ b/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts @@ -0,0 +1,11 @@ +module X { + export enum Foo { + A, B + } +} +module Y { + export enum Foo { + A, B + } +} +const y: X.Foo | boolean = Y.Foo.A; From 5f0ada1164e12a9da23cc30deeeaa722a3c55c8a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 8 Sep 2016 15:30:29 -0700 Subject: [PATCH 05/14] Fix both new enum assignability predicates And update error reporting baseline (new error is less elaborate) --- src/compiler/checker.ts | 14 ++++++++------ .../reference/enumAssignmentCompat3.errors.txt | 6 ++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ddb250255ee..6a96ca1c517 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6234,13 +6234,15 @@ namespace ts { if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true; if (relation === assignableRelation || relation === comparableRelation) { if (source.flags & TypeFlags.Any) return true; - if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && target.flags & TypeFlags.Enum) return true; - if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && - target.flags & TypeFlags.Union && - forEach((target as UnionType).types, t => t.flags & TypeFlags.EnumLike)) return true; - if (source.flags & (TypeFlags.NumberLiteral | TypeFlags.EnumLiteral) && + if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && target.flags & TypeFlags.EnumLike) return true; + if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.EnumLiteral && (source).text === (target).text) return true; + if (source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral && - (source).text === (target).text) return true; + (source).text === (target).text && + (source).baseType.symbol.name === (target).baseType.symbol.name && + !isConstEnumSymbol((source).baseType.symbol) && !isConstEnumSymbol((target).baseType.symbol)) { + return true; + } } return false; } diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index 02cb4314777..bfdaef96775 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -1,7 +1,6 @@ tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. 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'. @@ -89,8 +88,7 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged. abc = secondAb; // ok abc = secondCd; // missing 'd' ~~~ -!!! error TS2322: Type 'Cd.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 = nope; // nope! ~~~ !!! error TS2322: Type 'Nope' is not assignable to type 'E'. From 8f40620debe7988de1017395388833bb1656226d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 09:59:23 -0700 Subject: [PATCH 06/14] Address PR comments 1. Cache results of isEnumTypeRelatedTo 2. Make numeric literal assignment stricter again. 3. Use isEnumRelatedTo for comparing enums to each other. This provides the previous semi-structural semantics. 4. Because of the new distinction between computed enums (no union members) and union enums (no computed values => a union of enum literals), some semi-structural code moves out to the body of `isRelatedTo`. --- src/compiler/checker.ts | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6a96ca1c517..359a4b67b25 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -334,6 +334,7 @@ namespace ts { const assignableRelation = createMap(); const comparableRelation = createMap(); const identityRelation = createMap(); + const enumRelation = createMap(); // This is for caching the result of getSymbolDisplayBuilder. Do not access directly. let _displayBuilder: SymbolDisplayBuilder; @@ -6203,7 +6204,12 @@ namespace ts { if (source === target) { return true; } + const id = source.id + "," + target.id; + if (enumRelation[id] !== undefined) { + return enumRelation[id]; + } if (source.symbol.name !== target.symbol.name || !(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum)) { + enumRelation[id] = false; return false; } const targetEnumType = getTypeOfSymbol(target.symbol); @@ -6215,10 +6221,12 @@ namespace ts { errorReporter(Diagnostics.Property_0_is_missing_in_type_1, property.name, typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); } + enumRelation[id] = false; return false; } } } + enumRelation[id] = true; return true; } @@ -6234,13 +6242,18 @@ namespace ts { if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true; if (relation === assignableRelation || relation === comparableRelation) { if (source.flags & TypeFlags.Any) return true; - if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && target.flags & TypeFlags.EnumLike) return true; + if (source.flags & TypeFlags.Number && target.flags & TypeFlags.EnumLike) return true; + if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.Enum) return true; if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.EnumLiteral && (source).text === (target).text) return true; if (source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral && (source).text === (target).text && - (source).baseType.symbol.name === (target).baseType.symbol.name && - !isConstEnumSymbol((source).baseType.symbol) && !isConstEnumSymbol((target).baseType.symbol)) { + isEnumTypeRelatedTo((source).baseType, (target).baseType, errorReporter)) { + return true; + } + if (source.flags & TypeFlags.EnumLiteral && + target.flags & TypeFlags.Enum && + isEnumTypeRelatedTo(target, (source).baseType, errorReporter)) { return true; } } @@ -6418,6 +6431,14 @@ namespace ts { if (result = typeRelatedToSomeType(source, target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive))) { return result; } + if (source.flags & TypeFlags.Enum) { + // 1. look through the target union for a literal whose base type is related to the source + let lit = find((target).types, t => t.flags & TypeFlags.EnumLiteral && isEnumTypeRelatedTo(source, (t).baseType)); + // 2. if found, the base type is only assignable to source if all its literals are in the target union. + if (lit && (result = isRelatedTo((lit as EnumLiteralType).baseType, target, false))) { + return result; + } + } } } From e90f5e063e155d926970e5e770bf560df4f12e98 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 10:05:48 -0700 Subject: [PATCH 07/14] 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 From 9861c0f676a0665fe105a1b89584a70d8bec5a82 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 10:07:21 -0700 Subject: [PATCH 08/14] Fix lint --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 359a4b67b25..cc2d36339d5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6433,9 +6433,9 @@ namespace ts { } if (source.flags & TypeFlags.Enum) { // 1. look through the target union for a literal whose base type is related to the source - let lit = find((target).types, t => t.flags & TypeFlags.EnumLiteral && isEnumTypeRelatedTo(source, (t).baseType)); + const lit = find((target).types, t => t.flags & TypeFlags.EnumLiteral && isEnumTypeRelatedTo(source, (t).baseType)); // 2. if found, the base type is only assignable to source if all its literals are in the target union. - if (lit && (result = isRelatedTo((lit as EnumLiteralType).baseType, target, false))) { + if (lit && (result = isRelatedTo((lit as EnumLiteralType).baseType, target, /*reportErrors*/ false))) { return result; } } From b497cc5e4c883be8975cc83c31f449800ba08feb Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 10:14:48 -0700 Subject: [PATCH 09/14] Update baselines --- .../reference/numberAssignableToEnumInsideUnion.types | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/numberAssignableToEnumInsideUnion.types b/tests/baselines/reference/numberAssignableToEnumInsideUnion.types index fd45ff17622..56d6efb0d1e 100644 --- a/tests/baselines/reference/numberAssignableToEnumInsideUnion.types +++ b/tests/baselines/reference/numberAssignableToEnumInsideUnion.types @@ -1,8 +1,8 @@ === tests/cases/compiler/numberAssignableToEnumInsideUnion.ts === enum E { A, B } >E : E ->A : E ->B : E +>A : E.A +>B : E.B let n: number; >n : number From 977b788559097940938afc10d5a8ec0ad34f90db Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 14:11:47 -0700 Subject: [PATCH 10/14] Enum assignability:loosen numbers+tighten computed 1. All numbers and numeric literals are assignable to all enums and enum literals. 2. Computed enums are no longer assignable to anything except themselves, even if they would otherwise be "semi-structurally" compatible. --- src/compiler/checker.ts | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 99341bdf7d5..198c329d709 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6211,9 +6211,10 @@ namespace ts { if (enumRelation[id] !== undefined) { return enumRelation[id]; } - if (source.symbol.name !== target.symbol.name || !(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum)) { - enumRelation[id] = false; - return false; + if (source.symbol.name !== target.symbol.name || + !(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum) || + !(source.flags & TypeFlags.Union) || !(target.flags & TypeFlags.Union)) { + return (enumRelation[id] = false); } const targetEnumType = getTypeOfSymbol(target.symbol); for (const property of getPropertiesOfType(getTypeOfSymbol(source.symbol))) { @@ -6224,13 +6225,11 @@ namespace ts { errorReporter(Diagnostics.Property_0_is_missing_in_type_1, property.name, typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); } - enumRelation[id] = false; - return false; + return (enumRelation[id] = false); } } } - enumRelation[id] = true; - return true; + return (enumRelation[id] = true); } function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter) { @@ -6245,9 +6244,7 @@ namespace ts { if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true; if (relation === assignableRelation || relation === comparableRelation) { if (source.flags & TypeFlags.Any) return true; - if (source.flags & TypeFlags.Number && target.flags & TypeFlags.EnumLike) return true; - if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.Enum) return true; - if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.EnumLiteral && (source).text === (target).text) return true; + if ((source.flags & TypeFlags.Number | source.flags & TypeFlags.NumberLiteral) && target.flags & TypeFlags.EnumLike) return true; if (source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral && (source).text === (target).text && @@ -6434,14 +6431,6 @@ namespace ts { if (result = typeRelatedToSomeType(source, target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive))) { return result; } - if (source.flags & TypeFlags.Enum) { - // 1. look through the target union for a literal whose base type is related to the source - const lit = find((target).types, t => t.flags & TypeFlags.EnumLiteral && isEnumTypeRelatedTo(source, (t).baseType)); - // 2. if found, the base type is only assignable to source if all its literals are in the target union. - if (lit && (result = isRelatedTo((lit as EnumLiteralType).baseType, target, /*reportErrors*/ false))) { - return result; - } - } } } From 5cf99e605adf559bff9a0c4ffbb81312bf636ecc Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 14:13:17 -0700 Subject: [PATCH 11/14] Update baselines for updated enum assignability --- .../reference/enumAssignmentCompat.errors.txt | 5 +- .../enumAssignmentCompat2.errors.txt | 5 +- .../enumAssignmentCompat3.errors.txt | 8 ++- .../enumAssignmentCompat5.errors.txt | 5 +- ...eralAssignableToEnumInsideUnion.errors.txt | 20 ++++-- .../enumLiteralAssignableToEnumInsideUnion.js | 10 +-- ...LiteralAssignableToEnumInsideUnion.symbols | 66 ----------------- ...umLiteralAssignableToEnumInsideUnion.types | 72 ------------------- .../enumLiteralAssignableToEnumInsideUnion.ts | 5 +- 9 files changed, 34 insertions(+), 162 deletions(-) delete mode 100644 tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols delete mode 100644 tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types diff --git a/tests/baselines/reference/enumAssignmentCompat.errors.txt b/tests/baselines/reference/enumAssignmentCompat.errors.txt index 11f2d026261..d0b8cb376c2 100644 --- a/tests/baselines/reference/enumAssignmentCompat.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat.errors.txt @@ -1,12 +1,11 @@ tests/cases/compiler/enumAssignmentCompat.ts(26,5): error TS2322: Type 'typeof W' is not assignable to type 'number'. tests/cases/compiler/enumAssignmentCompat.ts(28,5): error TS2322: Type 'W.a' is not assignable to type 'typeof W'. tests/cases/compiler/enumAssignmentCompat.ts(30,5): error TS2322: Type '3' is not assignable to type 'typeof W'. -tests/cases/compiler/enumAssignmentCompat.ts(31,5): error TS2322: Type '4' is not assignable to type 'W.a'. tests/cases/compiler/enumAssignmentCompat.ts(32,5): error TS2322: Type 'W.a' is not assignable to type 'WStatic'. tests/cases/compiler/enumAssignmentCompat.ts(33,5): error TS2322: Type '5' is not assignable to type 'WStatic'. -==== tests/cases/compiler/enumAssignmentCompat.ts (6 errors) ==== +==== tests/cases/compiler/enumAssignmentCompat.ts (5 errors) ==== module W { export class D { } } @@ -44,8 +43,6 @@ tests/cases/compiler/enumAssignmentCompat.ts(33,5): error TS2322: Type '5' is no ~ !!! error TS2322: Type '3' is not assignable to type 'typeof W'. var e: typeof W.a = 4; - ~ -!!! error TS2322: Type '4' is not assignable to type 'W.a'. var f: WStatic = W.a; // error ~ !!! error TS2322: Type 'W.a' is not assignable to type 'WStatic'. diff --git a/tests/baselines/reference/enumAssignmentCompat2.errors.txt b/tests/baselines/reference/enumAssignmentCompat2.errors.txt index 9cda6325434..065cd35133d 100644 --- a/tests/baselines/reference/enumAssignmentCompat2.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat2.errors.txt @@ -1,12 +1,11 @@ tests/cases/compiler/enumAssignmentCompat2.ts(25,5): error TS2322: Type 'typeof W' is not assignable to type 'number'. tests/cases/compiler/enumAssignmentCompat2.ts(27,5): error TS2322: Type 'W.a' is not assignable to type 'typeof W'. tests/cases/compiler/enumAssignmentCompat2.ts(29,5): error TS2322: Type '3' is not assignable to type 'typeof W'. -tests/cases/compiler/enumAssignmentCompat2.ts(30,5): error TS2322: Type '4' is not assignable to type 'W.a'. tests/cases/compiler/enumAssignmentCompat2.ts(31,5): error TS2322: Type 'W.a' is not assignable to type 'WStatic'. tests/cases/compiler/enumAssignmentCompat2.ts(32,5): error TS2322: Type '5' is not assignable to type 'WStatic'. -==== tests/cases/compiler/enumAssignmentCompat2.ts (6 errors) ==== +==== tests/cases/compiler/enumAssignmentCompat2.ts (5 errors) ==== enum W { a, b, c, @@ -43,8 +42,6 @@ tests/cases/compiler/enumAssignmentCompat2.ts(32,5): error TS2322: Type '5' is n ~ !!! error TS2322: Type '3' is not assignable to type 'typeof W'. var e: typeof W.a = 4; - ~ -!!! error TS2322: Type '4' is not assignable to type 'W.a'. var f: WStatic = W.a; // error ~ !!! error TS2322: Type 'W.a' is not assignable to type 'WStatic'. diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index 41fa7a94fca..558540c32c8 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -2,15 +2,17 @@ tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2324: Property 'd' 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(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'. +tests/cases/compiler/enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Decl.E' is not assignable to type 'First.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'. tests/cases/compiler/enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'. +tests/cases/compiler/enumAssignmentCompat3.ts(78,1): error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. 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 TS2324: Property 'd' is missing in type 'First.E'. -==== tests/cases/compiler/enumAssignmentCompat3.ts (9 errors) ==== +==== tests/cases/compiler/enumAssignmentCompat3.ts (11 errors) ==== namespace First { export enum E { a, b, c, @@ -90,6 +92,8 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2324: Property 'd' ~~~ !!! error TS2322: Type 'Nope' is not assignable to type 'E'. abc = decl; // ok + ~~~ +!!! error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' @@ -102,6 +106,8 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2324: Property 'd' ~~~~ !!! error TS2322: Type 'E' is not assignable to type 'Nope'. decl = abc; // ok + ~~~~ +!!! error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. // const is only assignable to itself k = k; diff --git a/tests/baselines/reference/enumAssignmentCompat5.errors.txt b/tests/baselines/reference/enumAssignmentCompat5.errors.txt index 98c0aaccfad..ef703a2ad62 100644 --- a/tests/baselines/reference/enumAssignmentCompat5.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat5.errors.txt @@ -1,8 +1,7 @@ -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) ==== +==== tests/cases/compiler/enumAssignmentCompat5.ts (1 errors) ==== enum E { A, B, C } @@ -17,8 +16,6 @@ tests/cases/compiler/enumAssignmentCompat5.ts(20,9): error TS2535: Enum type 'Co 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 diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt index 37bdc99a922..f79a9d19cd6 100644 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt @@ -1,8 +1,11 @@ -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(24,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. +tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(25,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. +tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(26,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.B'. +tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(27,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'. +tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(28,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. -==== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts (2 errors) ==== +==== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts (5 errors) ==== module X { export enum Foo { A, B @@ -25,8 +28,13 @@ tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(26,7): error TS23 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 e0: X.Foo | boolean = Y.Foo.A; // ok + const e1: X.Foo | boolean = Z.Foo.A; // not legal, Z is computed + ~~ +!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. + const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // still not legal + ~~ +!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. const e3: X.Foo.B | boolean = Z.Foo.A; // not legal ~~ !!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.B'. @@ -34,4 +42,6 @@ tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(26,7): error TS23 ~~ !!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'. const e5: Ka.Foo | boolean = Z.Foo.A; // ok + ~~ +!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. \ No newline at end of file diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js index 1665e729719..8786745a504 100644 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.js @@ -21,8 +21,9 @@ module Ka { 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 e0: X.Foo | boolean = Y.Foo.A; // ok +const e1: X.Foo | boolean = Z.Foo.A; // not legal, Z is computed +const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // still not legal 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 @@ -61,8 +62,9 @@ var Ka; })(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 e0 = Y.Foo.A; // ok +var e1 = Z.Foo.A; // not legal, Z is computed +var e2 = Z.Foo.A; // still not legal 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 deleted file mode 100644 index 8df8e21b386..00000000000 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.symbols +++ /dev/null @@ -1,66 +0,0 @@ -=== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts === -module X { ->X : Symbol(X, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 0)) - - export enum Foo { ->Foo : Symbol(Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 0, 10)) - - A, B ->A : Symbol(Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 1, 21)) ->B : Symbol(Foo.B, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 2, 10)) - } -} -module Y { ->Y : Symbol(Y, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 4, 1)) - - export enum Foo { ->Foo : Symbol(Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 5, 10)) - - A, B ->A : Symbol(Foo.A, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 6, 21)) ->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, 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)) ->Y.Foo : Symbol(Y.Foo, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 5, 10)) ->Y : Symbol(Y, Decl(enumLiteralAssignableToEnumInsideUnion.ts, 4, 1)) ->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 deleted file mode 100644 index 5dbb98bcf9c..00000000000 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.types +++ /dev/null @@ -1,72 +0,0 @@ -=== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts === -module X { ->X : typeof X - - export enum Foo { ->Foo : Foo - - A, B ->A : Foo ->B : Foo - } -} -module Y { ->Y : typeof Y - - export enum Foo { ->Foo : Foo - - A, B ->A : Foo ->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 ->Foo : X.Foo ->Y.Foo.A : Y.Foo ->Y.Foo : typeof Y.Foo ->Y : typeof Y ->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/enumLiteralAssignableToEnumInsideUnion.ts b/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts index c3029af0f42..19cd98fd5e8 100644 --- a/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts +++ b/tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts @@ -20,8 +20,9 @@ module Ka { 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 e0: X.Foo | boolean = Y.Foo.A; // ok +const e1: X.Foo | boolean = Z.Foo.A; // not legal, Z is computed +const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // still not legal 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 From cf36fafe9a8c6d6ef2fbf85779cf99c456f34276 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 14:43:24 -0700 Subject: [PATCH 12/14] Computed enum assignability is semi-structural --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 198c329d709..37698f0af5f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6213,7 +6213,7 @@ namespace ts { } if (source.symbol.name !== target.symbol.name || !(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum) || - !(source.flags & TypeFlags.Union) || !(target.flags & TypeFlags.Union)) { + (source.flags & TypeFlags.Union) !== (target.flags & TypeFlags.Union)) { return (enumRelation[id] = false); } const targetEnumType = getTypeOfSymbol(target.symbol); From c071b397b209e527fec28bd59ba6efdea62104cf Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 14:43:44 -0700 Subject: [PATCH 13/14] Update baselines --- .../enumLiteralAssignableToEnumInsideUnion.errors.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt index f79a9d19cd6..660e1094ae9 100644 --- a/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt +++ b/tests/baselines/reference/enumLiteralAssignableToEnumInsideUnion.errors.txt @@ -2,10 +2,9 @@ tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(24,7): error TS23 tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(25,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(26,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.B'. tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(27,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'. -tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(28,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. -==== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts (5 errors) ==== +==== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts (4 errors) ==== module X { export enum Foo { A, B @@ -42,6 +41,4 @@ tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(28,7): error TS23 ~~ !!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'. const e5: Ka.Foo | boolean = Z.Foo.A; // ok - ~~ -!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'. \ No newline at end of file From 5ed065329531898513d16e6802dd7e9de715d59b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Tue, 13 Sep 2016 08:48:07 -0700 Subject: [PATCH 14/14] Remove unnecessary parentheses --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 37698f0af5f..5fb9316e397 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6214,7 +6214,7 @@ namespace ts { if (source.symbol.name !== target.symbol.name || !(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum) || (source.flags & TypeFlags.Union) !== (target.flags & TypeFlags.Union)) { - return (enumRelation[id] = false); + return enumRelation[id] = false; } const targetEnumType = getTypeOfSymbol(target.symbol); for (const property of getPropertiesOfType(getTypeOfSymbol(source.symbol))) { @@ -6225,11 +6225,11 @@ namespace ts { errorReporter(Diagnostics.Property_0_is_missing_in_type_1, property.name, typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); } - return (enumRelation[id] = false); + return enumRelation[id] = false; } } } - return (enumRelation[id] = true); + return enumRelation[id] = true; } function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter) {