From 977b788559097940938afc10d5a8ec0ad34f90db Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Sep 2016 14:11:47 -0700 Subject: [PATCH] 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; - } - } } }