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.
This commit is contained in:
Nathan Shively-Sanders 2016-09-12 14:11:47 -07:00
parent e384317173
commit d0f8be535e

View file

@ -6200,9 +6200,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))) {
@ -6213,13 +6214,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<RelationComparisonResult>, errorReporter?: ErrorReporter) {
@ -6234,9 +6233,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 && (<LiteralType>source).text === (<LiteralType>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 &&
(<LiteralType>source).text === (<LiteralType>target).text &&
@ -6423,14 +6420,6 @@ namespace ts {
if (result = typeRelatedToSomeType(source, <UnionType>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((<UnionType>target).types, t => t.flags & TypeFlags.EnumLiteral && isEnumTypeRelatedTo(<EnumType>source, (<EnumLiteralType>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;
}
}
}
}