Merge pull request #15486 from Microsoft/literalEnumTypes

String valued members in enums
This commit is contained in:
Anders Hejlsberg
2017-05-17 13:06:20 -07:00
committed by GitHub
45 changed files with 3787 additions and 618 deletions
+312 -333
View File
@@ -47,6 +47,7 @@ namespace ts {
let typeCount = 0;
let symbolCount = 0;
let enumCount = 0;
let symbolInstantiationDepth = 0;
const emptyArray: any[] = [];
@@ -214,8 +215,7 @@ namespace ts {
const tupleTypes: GenericType[] = [];
const unionTypes = createMap<UnionType>();
const intersectionTypes = createMap<IntersectionType>();
const stringLiteralTypes = createMap<LiteralType>();
const numericLiteralTypes = createMap<LiteralType>();
const literalTypes = createMap<LiteralType>();
const indexedAccessTypes = createMap<IndexedAccessType>();
const evolvingArrayTypes: EvolvingArrayType[] = [];
@@ -313,8 +313,8 @@ namespace ts {
let flowLoopCount = 0;
let visitedFlowCount = 0;
const emptyStringType = getLiteralTypeForText(TypeFlags.StringLiteral, "");
const zeroType = getLiteralTypeForText(TypeFlags.NumberLiteral, "0");
const emptyStringType = getLiteralType("");
const zeroType = getLiteralType(0);
const resolutionTargets: TypeSystemEntity[] = [];
const resolutionResults: boolean[] = [];
@@ -1903,7 +1903,7 @@ namespace ts {
}
function createTypeofType() {
return getUnionType(convertToArray(typeofEQFacts.keys(), s => getLiteralTypeForText(TypeFlags.StringLiteral, s)));
return getUnionType(convertToArray(typeofEQFacts.keys(), getLiteralType));
}
// A reserved member name starts with two underscores, but the third character cannot be an underscore
@@ -2376,26 +2376,25 @@ namespace ts {
if (type.flags & TypeFlags.Boolean) {
return createKeywordTypeNode(SyntaxKind.BooleanKeyword);
}
if (type.flags & TypeFlags.Enum) {
if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) {
const parentSymbol = getParentOfSymbol(type.symbol);
const parentName = symbolToName(parentSymbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
const enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type ? parentName : createQualifiedName(parentName, getNameOfSymbol(type.symbol, context));
return createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined);
}
if (type.flags & TypeFlags.EnumLike) {
const name = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
}
if (type.flags & (TypeFlags.StringLiteral)) {
return createLiteralTypeNode(setEmitFlags(createLiteral((<LiteralType>type).text), EmitFlags.NoAsciiEscaping));
return createLiteralTypeNode(setEmitFlags(createLiteral((<StringLiteralType>type).value), EmitFlags.NoAsciiEscaping));
}
if (type.flags & (TypeFlags.NumberLiteral)) {
return createLiteralTypeNode((createNumericLiteral((<LiteralType>type).text)));
return createLiteralTypeNode((createLiteral((<NumberLiteralType>type).value)));
}
if (type.flags & TypeFlags.BooleanLiteral) {
return (<IntrinsicType>type).intrinsicName === "true" ? createTrue() : createFalse();
}
if (type.flags & TypeFlags.EnumLiteral) {
const parentSymbol = getParentOfSymbol(type.symbol);
const parentName = symbolToName(parentSymbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
const name = getNameOfSymbol(type.symbol, context);
const enumLiteralName = createQualifiedName(parentName, name);
return createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined);
}
if (type.flags & TypeFlags.Void) {
return createKeywordTypeNode(SyntaxKind.VoidKeyword);
}
@@ -2820,7 +2819,7 @@ namespace ts {
let parameterType = getTypeOfSymbol(parameterSymbol);
if (isRequiredInitializedParameter(parameterDeclaration)) {
parameterType = includeFalsyTypes(parameterType, TypeFlags.Undefined);
parameterType = getNullableType(parameterType, TypeFlags.Undefined);
}
const parameterTypeNode = typeToTypeNodeHelper(parameterType, context);
@@ -2972,12 +2971,14 @@ namespace ts {
flags |= t.flags;
if (!(t.flags & TypeFlags.Nullable)) {
if (t.flags & (TypeFlags.BooleanLiteral | TypeFlags.EnumLiteral)) {
const baseType = t.flags & TypeFlags.BooleanLiteral ? booleanType : (<EnumLiteralType>t).baseType;
const count = baseType.types.length;
if (i + count <= types.length && types[i + count - 1] === baseType.types[count - 1]) {
result.push(baseType);
i += count - 1;
continue;
const baseType = t.flags & TypeFlags.BooleanLiteral ? booleanType : getBaseTypeOfEnumLiteralType(<LiteralType>t);
if (baseType.flags & TypeFlags.Union) {
const count = (<UnionType>baseType).types.length;
if (i + count <= types.length && types[i + count - 1] === (<UnionType>baseType).types[count - 1]) {
result.push(baseType);
i += count - 1;
continue;
}
}
}
result.push(t);
@@ -3015,7 +3016,7 @@ namespace ts {
}
function literalTypeToString(type: LiteralType) {
return type.flags & TypeFlags.StringLiteral ? `"${escapeString((<LiteralType>type).text)}"` : (<LiteralType>type).text;
return type.flags & TypeFlags.StringLiteral ? `"${escapeString((<StringLiteralType>type).value)}"` : "" + (<NumberLiteralType>type).value;
}
function getNameOfSymbol(symbol: Symbol): string {
@@ -3176,12 +3177,17 @@ namespace ts {
else if (getObjectFlags(type) & ObjectFlags.Reference) {
writeTypeReference(<TypeReference>type, nextFlags);
}
else if (type.flags & TypeFlags.EnumLiteral) {
buildSymbolDisplay(getParentOfSymbol(type.symbol), writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
writePunctuation(writer, SyntaxKind.DotToken);
appendSymbolNameOnly(type.symbol, writer);
else if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) {
const parent = getParentOfSymbol(type.symbol);
buildSymbolDisplay(parent, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
// In a literal enum type with a single member E { A }, E and E.A denote the
// same type. We always display this type simply as E.
if (getDeclaredTypeOfSymbol(parent) !== type) {
writePunctuation(writer, SyntaxKind.DotToken);
appendSymbolNameOnly(type.symbol, writer);
}
}
else if (getObjectFlags(type) & ObjectFlags.ClassOrInterface || type.flags & (TypeFlags.Enum | TypeFlags.TypeParameter)) {
else if (getObjectFlags(type) & ObjectFlags.ClassOrInterface || type.flags & (TypeFlags.EnumLike | TypeFlags.TypeParameter)) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
@@ -3552,7 +3558,7 @@ namespace ts {
let type = getTypeOfSymbol(p);
if (parameterNode && isRequiredInitializedParameter(parameterNode)) {
type = includeFalsyTypes(type, TypeFlags.Undefined);
type = getNullableType(type, TypeFlags.Undefined);
}
buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack);
}
@@ -4128,7 +4134,7 @@ namespace ts {
}
function addOptionality(type: Type, optional: boolean): Type {
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
return strictNullChecks && optional ? getNullableType(type, TypeFlags.Undefined) : type;
}
// Return the inferred type for a variable, parameter, or property declaration
@@ -4555,7 +4561,7 @@ namespace ts {
links.type = baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type;
}
else {
links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? getNullableType(type, TypeFlags.Undefined) : type;
}
}
}
@@ -5039,77 +5045,80 @@ namespace ts {
return links.declaredType;
}
function isLiteralEnumMember(symbol: Symbol, member: EnumMember) {
function isLiteralEnumMember(member: EnumMember) {
const expr = member.initializer;
if (!expr) {
return !isInAmbientContext(member);
}
return expr.kind === SyntaxKind.NumericLiteral ||
return expr.kind === SyntaxKind.StringLiteral || expr.kind === SyntaxKind.NumericLiteral ||
expr.kind === SyntaxKind.PrefixUnaryExpression && (<PrefixUnaryExpression>expr).operator === SyntaxKind.MinusToken &&
(<PrefixUnaryExpression>expr).operand.kind === SyntaxKind.NumericLiteral ||
expr.kind === SyntaxKind.Identifier && !!symbol.exports.get((<Identifier>expr).text);
expr.kind === SyntaxKind.Identifier && (nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get((<Identifier>expr).text));
}
function enumHasLiteralMembers(symbol: Symbol) {
function getEnumKind(symbol: Symbol): EnumKind {
const links = getSymbolLinks(symbol);
if (links.enumKind !== undefined) {
return links.enumKind;
}
let hasNonLiteralMember = false;
for (const declaration of symbol.declarations) {
if (declaration.kind === SyntaxKind.EnumDeclaration) {
for (const member of (<EnumDeclaration>declaration).members) {
if (!isLiteralEnumMember(symbol, member)) {
return false;
if (member.initializer && member.initializer.kind === SyntaxKind.StringLiteral) {
return links.enumKind = EnumKind.Literal;
}
if (!isLiteralEnumMember(member)) {
hasNonLiteralMember = true;
}
}
}
}
return true;
return links.enumKind = hasNonLiteralMember ? EnumKind.Numeric : EnumKind.Literal;
}
function createEnumLiteralType(symbol: Symbol, baseType: EnumType, text: string) {
const type = <EnumLiteralType>createType(TypeFlags.EnumLiteral);
type.symbol = symbol;
type.baseType = <EnumType & UnionType>baseType;
type.text = text;
return type;
function getBaseTypeOfEnumLiteralType(type: Type) {
return type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)) : type;
}
function getDeclaredTypeOfEnum(symbol: Symbol): Type {
const links = getSymbolLinks(symbol);
if (!links.declaredType) {
const enumType = links.declaredType = <EnumType>createType(TypeFlags.Enum);
enumType.symbol = symbol;
if (enumHasLiteralMembers(symbol)) {
const memberTypeList: Type[] = [];
const memberTypes: EnumLiteralType[] = [];
for (const declaration of enumType.symbol.declarations) {
if (declaration.kind === SyntaxKind.EnumDeclaration) {
computeEnumMemberValues(<EnumDeclaration>declaration);
for (const member of (<EnumDeclaration>declaration).members) {
const memberSymbol = getSymbolOfNode(member);
const value = getEnumMemberValue(member);
if (!memberTypes[value]) {
const memberType = memberTypes[value] = createEnumLiteralType(memberSymbol, enumType, "" + value);
memberTypeList.push(memberType);
}
}
if (links.declaredType) {
return links.declaredType;
}
if (getEnumKind(symbol) === EnumKind.Literal) {
enumCount++;
const memberTypeList: Type[] = [];
for (const declaration of symbol.declarations) {
if (declaration.kind === SyntaxKind.EnumDeclaration) {
for (const member of (<EnumDeclaration>declaration).members) {
const memberType = getLiteralType(getEnumMemberValue(member), enumCount, getSymbolOfNode(member));
getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType;
memberTypeList.push(memberType);
}
}
enumType.memberTypes = memberTypes;
if (memberTypeList.length > 1) {
enumType.flags |= TypeFlags.Union;
(<EnumType & UnionType>enumType).types = memberTypeList;
unionTypes.set(getTypeListId(memberTypeList), <EnumType & UnionType>enumType);
}
if (memberTypeList.length) {
const enumType = getUnionType(memberTypeList, /*subtypeReduction*/ false, symbol, /*aliasTypeArguments*/ undefined);
if (enumType.flags & TypeFlags.Union) {
enumType.flags |= TypeFlags.EnumLiteral;
enumType.symbol = symbol;
}
return links.declaredType = enumType;
}
}
return links.declaredType;
const enumType = createType(TypeFlags.Enum);
enumType.symbol = symbol;
return links.declaredType = enumType;
}
function getDeclaredTypeOfEnumMember(symbol: Symbol): Type {
const links = getSymbolLinks(symbol);
if (!links.declaredType) {
const enumType = <EnumType>getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
links.declaredType = enumType.flags & TypeFlags.Union ?
enumType.memberTypes[getEnumMemberValue(<EnumMember>symbol.valueDeclaration)] :
enumType;
const enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
if (!links.declaredType) {
links.declaredType = enumType;
}
}
return links.declaredType;
}
@@ -5640,7 +5649,7 @@ namespace ts {
// If the current iteration type constituent is a string literal type, create a property.
// Otherwise, for type string create a string index signature.
if (t.flags & TypeFlags.StringLiteral) {
const propName = (<LiteralType>t).text;
const propName = (<StringLiteralType>t).value;
const modifiersProp = getPropertyOfType(modifiersType, propName);
const isOptional = templateOptional || !!(modifiersProp && modifiersProp.flags & SymbolFlags.Optional);
const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName);
@@ -7365,7 +7374,7 @@ namespace ts {
function getLiteralTypeFromPropertyName(prop: Symbol) {
return getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || startsWith(prop.name, "__@") ?
neverType :
getLiteralTypeForText(TypeFlags.StringLiteral, unescapeIdentifier(prop.name));
getLiteralType(unescapeIdentifier(prop.name));
}
function getLiteralTypeFromPropertyNames(type: Type) {
@@ -7401,8 +7410,8 @@ namespace ts {
function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode, cacheSymbol: boolean) {
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? <ElementAccessExpression>accessNode : undefined;
const propName = indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral) ?
(<LiteralType>indexType).text :
const propName = indexType.flags & TypeFlags.StringOrNumberLiteral ?
"" + (<LiteralType>indexType).value :
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
getPropertyNameForKnownSymbolName((<Identifier>(<PropertyAccessExpression>accessExpression.argumentExpression).name).text) :
undefined;
@@ -7450,7 +7459,7 @@ namespace ts {
if (accessNode) {
const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? (<ElementAccessExpression>accessNode).argumentExpression : (<IndexedAccessTypeNode>accessNode).indexType;
if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, (<LiteralType>indexType).text, typeToString(objectType));
error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, "" + (<LiteralType>indexType).value, typeToString(objectType));
}
else if (indexType.flags & (TypeFlags.String | TypeFlags.Number)) {
error(indexNode, Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType));
@@ -7661,16 +7670,17 @@ namespace ts {
return prop.flags & SymbolFlags.Method && find(prop.declarations, decl => isClassLike(decl.parent));
}
function createLiteralType(flags: TypeFlags, text: string) {
function createLiteralType(flags: TypeFlags, value: string | number, symbol: Symbol) {
const type = <LiteralType>createType(flags);
type.text = text;
type.symbol = symbol;
type.value = value;
return type;
}
function getFreshTypeOfLiteralType(type: Type) {
if (type.flags & TypeFlags.StringOrNumberLiteral && !(type.flags & TypeFlags.FreshLiteral)) {
if (!(<LiteralType>type).freshType) {
const freshType = <LiteralType>createLiteralType(type.flags | TypeFlags.FreshLiteral, (<LiteralType>type).text);
const freshType = <LiteralType>createLiteralType(type.flags | TypeFlags.FreshLiteral, (<LiteralType>type).value, (<LiteralType>type).symbol);
freshType.regularType = <LiteralType>type;
(<LiteralType>type).freshType = freshType;
}
@@ -7683,11 +7693,17 @@ namespace ts {
return type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral ? (<LiteralType>type).regularType : type;
}
function getLiteralTypeForText(flags: TypeFlags, text: string) {
const map = flags & TypeFlags.StringLiteral ? stringLiteralTypes : numericLiteralTypes;
let type = map.get(text);
function getLiteralType(value: string | number, enumId?: number, symbol?: Symbol) {
// We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
// where NNN is the text representation of a numeric literal and SSS are the characters
// of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where
// EEE is a unique id for the containing enum type.
const qualifier = typeof value === "number" ? "#" : "@";
const key = enumId ? enumId + qualifier + value : qualifier + value;
let type = literalTypes.get(key);
if (!type) {
map.set(text, type = createLiteralType(flags, text));
const flags = (typeof value === "number" ? TypeFlags.NumberLiteral : TypeFlags.StringLiteral) | (enumId ? TypeFlags.EnumLiteral : 0);
literalTypes.set(key, type = createLiteralType(flags, value, symbol));
}
return type;
}
@@ -8534,29 +8550,27 @@ namespace ts {
false;
}
function isEnumTypeRelatedTo(source: EnumType, target: EnumType, errorReporter?: ErrorReporter) {
if (source === target) {
function isEnumTypeRelatedTo(sourceSymbol: Symbol, targetSymbol: Symbol, errorReporter?: ErrorReporter) {
if (sourceSymbol === targetSymbol) {
return true;
}
const id = source.id + "," + target.id;
const id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol);
const relation = enumRelation.get(id);
if (relation !== undefined) {
return relation;
}
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)) {
if (sourceSymbol.name !== targetSymbol.name || !(sourceSymbol.flags & SymbolFlags.RegularEnum) || !(targetSymbol.flags & SymbolFlags.RegularEnum)) {
enumRelation.set(id, false);
return false;
}
const targetEnumType = getTypeOfSymbol(target.symbol);
for (const property of getPropertiesOfType(getTypeOfSymbol(source.symbol))) {
const targetEnumType = getTypeOfSymbol(targetSymbol);
for (const property of getPropertiesOfType(getTypeOfSymbol(sourceSymbol))) {
if (property.flags & SymbolFlags.EnumMember) {
const targetProperty = getPropertyOfType(targetEnumType, property.name);
if (!targetProperty || !(targetProperty.flags & SymbolFlags.EnumMember)) {
if (errorReporter) {
errorReporter(Diagnostics.Property_0_is_missing_in_type_1, property.name,
typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType));
typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType));
}
enumRelation.set(id, false);
return false;
@@ -8568,30 +8582,36 @@ namespace ts {
}
function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorReporter?: ErrorReporter) {
if (target.flags & TypeFlags.Never) return false;
if (target.flags & TypeFlags.Any || source.flags & TypeFlags.Never) return true;
if (source.flags & TypeFlags.StringLike && target.flags & TypeFlags.String) return true;
if (source.flags & TypeFlags.NumberLike && target.flags & TypeFlags.Number) return true;
if (source.flags & TypeFlags.BooleanLike && target.flags & TypeFlags.Boolean) return true;
if (source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.Enum && (<EnumLiteralType>source).baseType === target) return true;
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum && isEnumTypeRelatedTo(<EnumType>source, <EnumType>target, errorReporter)) return true;
if (source.flags & TypeFlags.Undefined && (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void))) return true;
if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true;
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.NonPrimitive) return true;
const s = source.flags;
const t = target.flags;
if (t & TypeFlags.Never) return false;
if (t & TypeFlags.Any || s & TypeFlags.Never) return true;
if (s & TypeFlags.StringLike && t & TypeFlags.String) return true;
if (s & TypeFlags.StringLiteral && s & TypeFlags.EnumLiteral &&
t & TypeFlags.StringLiteral && !(t & TypeFlags.EnumLiteral) &&
(<LiteralType>source).value === (<LiteralType>target).value) return true;
if (s & TypeFlags.NumberLike && t & TypeFlags.Number) return true;
if (s & TypeFlags.NumberLiteral && s & TypeFlags.EnumLiteral &&
t & TypeFlags.NumberLiteral && !(t & TypeFlags.EnumLiteral) &&
(<LiteralType>source).value === (<LiteralType>target).value) return true;
if (s & TypeFlags.BooleanLike && t & TypeFlags.Boolean) return true;
if (s & TypeFlags.Enum && t & TypeFlags.Enum && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true;
if (s & TypeFlags.EnumLiteral && t & TypeFlags.EnumLiteral) {
if (s & TypeFlags.Union && t & TypeFlags.Union && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true;
if (s & TypeFlags.Literal && t & TypeFlags.Literal &&
(<LiteralType>source).value === (<LiteralType>target).value &&
isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter)) return true;
}
if (s & TypeFlags.Undefined && (!strictNullChecks || t & (TypeFlags.Undefined | TypeFlags.Void))) return true;
if (s & TypeFlags.Null && (!strictNullChecks || t & TypeFlags.Null)) return true;
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive) return true;
if (relation === assignableRelation || relation === comparableRelation) {
if (source.flags & TypeFlags.Any) 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 &&
(<EnumLiteralType>source).text === (<EnumLiteralType>target).text &&
isEnumTypeRelatedTo((<EnumLiteralType>source).baseType, (<EnumLiteralType>target).baseType, errorReporter)) {
return true;
}
if (source.flags & TypeFlags.EnumLiteral &&
target.flags & TypeFlags.Enum &&
isEnumTypeRelatedTo(<EnumType>target, (<EnumLiteralType>source).baseType, errorReporter)) {
return true;
}
if (s & TypeFlags.Any) return true;
// Type number or any numeric literal type is assignable to any numeric enum type or any
// numeric enum literal type. This rule exists for backwards compatibility reasons because
// bit-flag enum types sometimes look like literal enum types with numeric literal values.
if (s & (TypeFlags.Number | TypeFlags.NumberLiteral) && !(s & TypeFlags.EnumLiteral) && (
t & TypeFlags.Enum || t & TypeFlags.NumberLiteral && t & TypeFlags.EnumLiteral)) return true;
}
return false;
}
@@ -9745,7 +9765,7 @@ namespace ts {
return getUnionType(types, /*subtypeReduction*/ true);
}
const supertype = getSupertypeOrUnion(primaryTypes);
return supertype && includeFalsyTypes(supertype, getFalsyFlagsOfTypes(types) & TypeFlags.Nullable);
return supertype && getNullableType(supertype, getFalsyFlagsOfTypes(types) & TypeFlags.Nullable);
}
function reportNoCommonSupertypeError(types: Type[], errorLocation: Node, errorMessageChainHead: DiagnosticMessageChain): void {
@@ -9810,26 +9830,26 @@ namespace ts {
function isLiteralType(type: Type): boolean {
return type.flags & TypeFlags.Boolean ? true :
type.flags & TypeFlags.Union ? type.flags & TypeFlags.Enum ? true : !forEach((<UnionType>type).types, t => !isUnitType(t)) :
isUnitType(type);
type.flags & TypeFlags.Union ? type.flags & TypeFlags.EnumLiteral ? true : !forEach((<UnionType>type).types, t => !isUnitType(t)) :
isUnitType(type);
}
function getBaseTypeOfLiteralType(type: Type): Type {
return type.flags & TypeFlags.StringLiteral ? stringType :
return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
type.flags & TypeFlags.StringLiteral ? stringType :
type.flags & TypeFlags.NumberLiteral ? numberType :
type.flags & TypeFlags.BooleanLiteral ? booleanType :
type.flags & TypeFlags.EnumLiteral ? (<EnumLiteralType>type).baseType :
type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((<UnionType>type).types, getBaseTypeOfLiteralType)) :
type;
type.flags & TypeFlags.BooleanLiteral ? booleanType :
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getBaseTypeOfLiteralType)) :
type;
}
function getWidenedLiteralType(type: Type): Type {
return type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType :
return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType :
type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType :
type.flags & TypeFlags.BooleanLiteral ? booleanType :
type.flags & TypeFlags.EnumLiteral ? (<EnumLiteralType>type).baseType :
type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((<UnionType>type).types, getWidenedLiteralType)) :
type;
type.flags & TypeFlags.BooleanLiteral ? booleanType :
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getWidenedLiteralType)) :
type;
}
/**
@@ -9853,24 +9873,10 @@ namespace ts {
// no flags for all other types (including non-falsy literal types).
function getFalsyFlags(type: Type): TypeFlags {
return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((<UnionType>type).types) :
type.flags & TypeFlags.StringLiteral ? (<LiteralType>type).text === "" ? TypeFlags.StringLiteral : 0 :
type.flags & TypeFlags.NumberLiteral ? (<LiteralType>type).text === "0" ? TypeFlags.NumberLiteral : 0 :
type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 :
type.flags & TypeFlags.PossiblyFalsy;
}
function includeFalsyTypes(type: Type, flags: TypeFlags) {
if ((getFalsyFlags(type) & flags) === flags) {
return type;
}
const types = [type];
if (flags & TypeFlags.StringLike) types.push(emptyStringType);
if (flags & TypeFlags.NumberLike) types.push(zeroType);
if (flags & TypeFlags.BooleanLike) types.push(falseType);
if (flags & TypeFlags.Void) types.push(voidType);
if (flags & TypeFlags.Undefined) types.push(undefinedType);
if (flags & TypeFlags.Null) types.push(nullType);
return getUnionType(types);
type.flags & TypeFlags.StringLiteral ? (<LiteralType>type).value === "" ? TypeFlags.StringLiteral : 0 :
type.flags & TypeFlags.NumberLiteral ? (<LiteralType>type).value === 0 ? TypeFlags.NumberLiteral : 0 :
type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 :
type.flags & TypeFlags.PossiblyFalsy;
}
function removeDefinitelyFalsyTypes(type: Type): Type {
@@ -9879,6 +9885,28 @@ namespace ts {
type;
}
function extractDefinitelyFalsyTypes(type: Type): Type {
return mapType(type, getDefinitelyFalsyPartOfType);
}
function getDefinitelyFalsyPartOfType(type: Type): Type {
return type.flags & TypeFlags.String ? emptyStringType :
type.flags & TypeFlags.Number ? zeroType :
type.flags & TypeFlags.Boolean || type === falseType ? falseType :
type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null) ||
type.flags & TypeFlags.StringLiteral && (<LiteralType>type).value === "" ||
type.flags & TypeFlags.NumberLiteral && (<LiteralType>type).value === 0 ? type :
neverType;
}
function getNullableType(type: Type, flags: TypeFlags): Type {
const missing = (flags & ~type.flags) & (TypeFlags.Undefined | TypeFlags.Null);
return missing === 0 ? type :
missing === TypeFlags.Undefined ? getUnionType([type, undefinedType]) :
missing === TypeFlags.Null ? getUnionType([type, nullType]) :
getUnionType([type, undefinedType, nullType]);
}
function getNonNullableType(type: Type): Type {
return strictNullChecks ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
}
@@ -10205,7 +10233,7 @@ namespace ts {
}
return;
}
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) ||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral) ||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
// Source and target are both unions or both intersections. If source and target
// are the same type, just relate each constituent type to itself.
@@ -10728,15 +10756,16 @@ namespace ts {
return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts;
}
if (flags & TypeFlags.StringLiteral) {
const isEmpty = (<LiteralType>type).value === "";
return strictNullChecks ?
(<LiteralType>type).text === "" ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts :
(<LiteralType>type).text === "" ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts;
isEmpty ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts :
isEmpty ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts;
}
if (flags & (TypeFlags.Number | TypeFlags.Enum)) {
return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts;
}
if (flags & (TypeFlags.NumberLiteral | TypeFlags.EnumLiteral)) {
const isZero = (<LiteralType>type).text === "0";
if (flags & TypeFlags.NumberLiteral) {
const isZero = (<LiteralType>type).value === 0;
return strictNullChecks ?
isZero ? TypeFacts.ZeroStrictFacts : TypeFacts.NonZeroStrictFacts :
isZero ? TypeFacts.ZeroFacts : TypeFacts.NonZeroFacts;
@@ -10968,7 +10997,7 @@ namespace ts {
}
return true;
}
if (source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.Enum && (<EnumLiteralType>source).baseType === target) {
if (source.flags & TypeFlags.EnumLiteral && getBaseTypeOfEnumLiteralType(<LiteralType>source) === target) {
return true;
}
return containsType(target.types, source);
@@ -11972,7 +12001,7 @@ namespace ts {
isInAmbientContext(declaration);
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
type === autoType || type === autoArrayType ? undefinedType :
includeFalsyTypes(type, TypeFlags.Undefined);
getNullableType(type, TypeFlags.Undefined);
const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
// A variable is considered uninitialized when it is possible to analyze the entire control flow graph
// from declaration to use, and when the variable's declared type doesn't include undefined but the
@@ -13814,7 +13843,7 @@ namespace ts {
// <CustomTag> Hello World </CustomTag>
const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
if (intrinsicElementsType !== unknownType) {
const stringLiteralTypeName = (<LiteralType>elementType).text;
const stringLiteralTypeName = (<StringLiteralType>elementType).value;
const intrinsicProp = getPropertyOfType(intrinsicElementsType, stringLiteralTypeName);
if (intrinsicProp) {
return getTypeOfSymbol(intrinsicProp);
@@ -15177,7 +15206,7 @@ namespace ts {
case SyntaxKind.Identifier:
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
return getLiteralTypeForText(TypeFlags.StringLiteral, (<Identifier | LiteralExpression>element.name).text);
return getLiteralType((<Identifier | LiteralExpression>element.name).text);
case SyntaxKind.ComputedPropertyName:
const nameType = checkComputedPropertyName(<ComputedPropertyName>element.name);
@@ -16070,7 +16099,7 @@ namespace ts {
if (strictNullChecks) {
const declaration = symbol.valueDeclaration;
if (declaration && (<VariableLikeDeclaration>declaration).initializer) {
return includeFalsyTypes(type, TypeFlags.Undefined);
return getNullableType(type, TypeFlags.Undefined);
}
}
return type;
@@ -16661,7 +16690,7 @@ namespace ts {
return silentNeverType;
}
if (node.operator === SyntaxKind.MinusToken && node.operand.kind === SyntaxKind.NumericLiteral) {
return getFreshTypeOfLiteralType(getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>node.operand).text));
return getFreshTypeOfLiteralType(getLiteralType(-(<LiteralExpression>node.operand).text));
}
switch (node.operator) {
case SyntaxKind.PlusToken:
@@ -17169,7 +17198,7 @@ namespace ts {
return checkInExpression(left, right, leftType, rightType);
case SyntaxKind.AmpersandAmpersandToken:
return getTypeFacts(leftType) & TypeFacts.Truthy ?
includeFalsyTypes(rightType, getFalsyFlags(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType))) :
getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) :
leftType;
case SyntaxKind.BarBarToken:
return getTypeFacts(leftType) & TypeFacts.Falsy ?
@@ -17341,9 +17370,9 @@ namespace ts {
}
switch (node.kind) {
case SyntaxKind.StringLiteral:
return getFreshTypeOfLiteralType(getLiteralTypeForText(TypeFlags.StringLiteral, (<LiteralExpression>node).text));
return getFreshTypeOfLiteralType(getLiteralType((<LiteralExpression>node).text));
case SyntaxKind.NumericLiteral:
return getFreshTypeOfLiteralType(getLiteralTypeForText(TypeFlags.NumberLiteral, (<LiteralExpression>node).text));
return getFreshTypeOfLiteralType(getLiteralType(+(<LiteralExpression>node).text));
case SyntaxKind.TrueKeyword:
return trueType;
case SyntaxKind.FalseKeyword:
@@ -18265,7 +18294,7 @@ namespace ts {
checkTypeArgumentConstraints(typeParameters, node.typeArguments);
}
}
if (type.flags & TypeFlags.Enum && !(<EnumType>type).memberTypes && getNodeLinks(node).resolvedSymbol.flags & SymbolFlags.EnumMember) {
if (type.flags & TypeFlags.Enum && getNodeLinks(node).resolvedSymbol.flags & SymbolFlags.EnumMember) {
error(node, Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
}
}
@@ -21053,107 +21082,91 @@ namespace ts {
function computeEnumMemberValues(node: EnumDeclaration) {
const nodeLinks = getNodeLinks(node);
if (!(nodeLinks.flags & NodeCheckFlags.EnumValuesComputed)) {
const enumSymbol = getSymbolOfNode(node);
const enumType = getDeclaredTypeOfSymbol(enumSymbol);
let autoValue = 0; // set to undefined when enum member is non-constant
const ambient = isInAmbientContext(node);
const enumIsConst = isConst(node);
for (const member of node.members) {
if (isComputedNonLiteralName(<PropertyName>member.name)) {
error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
else {
const text = getTextOfPropertyName(<PropertyName>member.name);
if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) {
error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name);
}
}
const previousEnumMemberIsNonConstant = autoValue === undefined;
const initializer = member.initializer;
if (initializer) {
autoValue = computeConstantValueForEnumMemberInitializer(initializer, enumType, enumIsConst, ambient);
}
else if (ambient && !enumIsConst) {
// In ambient enum declarations that specify no const modifier, enum member declarations
// that omit a value are considered computed members (as opposed to having auto-incremented values assigned).
autoValue = undefined;
}
else if (previousEnumMemberIsNonConstant) {
// If the member declaration specifies no value, the member is considered a constant enum member.
// If the member is the first member in the enum declaration, it is assigned the value zero.
// Otherwise, it is assigned the value of the immediately preceding member plus one,
// and an error occurs if the immediately preceding member is not a constant enum member
error(member.name, Diagnostics.Enum_member_must_have_initializer);
}
if (autoValue !== undefined) {
getNodeLinks(member).enumMemberValue = autoValue;
autoValue++;
}
}
nodeLinks.flags |= NodeCheckFlags.EnumValuesComputed;
}
function computeConstantValueForEnumMemberInitializer(initializer: Expression, enumType: Type, enumIsConst: boolean, ambient: boolean): number {
// Controls if error should be reported after evaluation of constant value is completed
// Can be false if another more precise error was already reported during evaluation.
let reportError = true;
const value = evalConstant(initializer);
if (reportError) {
if (value === undefined) {
if (enumIsConst) {
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
}
else if (ambient) {
error(initializer, Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
}
else {
// Only here do we need to check that the initializer is assignable to the enum type.
checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined);
}
}
else if (enumIsConst) {
if (isNaN(value)) {
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN);
}
else if (!isFinite(value)) {
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
}
}
let autoValue = 0;
for (const member of node.members) {
const value = computeMemberValue(member, autoValue);
getNodeLinks(member).enumMemberValue = value;
autoValue = typeof value === "number" ? value + 1 : undefined;
}
}
}
return value;
function computeMemberValue(member: EnumMember, autoValue: number) {
if (isComputedNonLiteralName(<PropertyName>member.name)) {
error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
else {
const text = getTextOfPropertyName(<PropertyName>member.name);
if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) {
error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name);
}
}
if (member.initializer) {
return computeConstantValue(member);
}
// In ambient enum declarations that specify no const modifier, enum member declarations that omit
// a value are considered computed members (as opposed to having auto-incremented values).
if (isInAmbientContext(member.parent) && !isConst(member.parent)) {
return undefined;
}
// If the member declaration specifies no value, the member is considered a constant enum member.
// If the member is the first member in the enum declaration, it is assigned the value zero.
// Otherwise, it is assigned the value of the immediately preceding member plus one, and an error
// occurs if the immediately preceding member is not a constant enum member.
if (autoValue !== undefined) {
return autoValue;
}
error(member.name, Diagnostics.Enum_member_must_have_initializer);
return undefined;
}
function evalConstant(e: Node): number {
switch (e.kind) {
case SyntaxKind.PrefixUnaryExpression:
const value = evalConstant((<PrefixUnaryExpression>e).operand);
if (value === undefined) {
return undefined;
}
switch ((<PrefixUnaryExpression>e).operator) {
function computeConstantValue(member: EnumMember): string | number {
const enumKind = getEnumKind(getSymbolOfNode(member.parent));
const isConstEnum = isConst(member.parent);
const initializer = member.initializer;
const value = enumKind === EnumKind.Literal && !isLiteralEnumMember(member) ? undefined : evaluate(initializer);
if (value !== undefined) {
if (isConstEnum && typeof value === "number" && !isFinite(value)) {
error(initializer, isNaN(value) ?
Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN :
Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
}
}
else if (enumKind === EnumKind.Literal) {
error(initializer, Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members);
return 0;
}
else if (isConstEnum) {
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
}
else if (isInAmbientContext(member.parent)) {
error(initializer, Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
}
else {
// Only here do we need to check that the initializer is assignable to the enum type.
checkTypeAssignableTo(checkExpression(initializer), getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
}
return value;
function evaluate(expr: Expression): string | number {
switch (expr.kind) {
case SyntaxKind.PrefixUnaryExpression:
const value = evaluate((<PrefixUnaryExpression>expr).operand);
if (typeof value === "number") {
switch ((<PrefixUnaryExpression>expr).operator) {
case SyntaxKind.PlusToken: return value;
case SyntaxKind.MinusToken: return -value;
case SyntaxKind.TildeToken: return ~value;
}
return undefined;
case SyntaxKind.BinaryExpression:
const left = evalConstant((<BinaryExpression>e).left);
if (left === undefined) {
return undefined;
}
const right = evalConstant((<BinaryExpression>e).right);
if (right === undefined) {
return undefined;
}
switch ((<BinaryExpression>e).operatorToken.kind) {
}
break;
case SyntaxKind.BinaryExpression:
const left = evaluate((<BinaryExpression>expr).left);
const right = evaluate((<BinaryExpression>expr).right);
if (typeof left === "number" && typeof right === "number") {
switch ((<BinaryExpression>expr).operatorToken.kind) {
case SyntaxKind.BarToken: return left | right;
case SyntaxKind.AmpersandToken: return left & right;
case SyntaxKind.GreaterThanGreaterThanToken: return left >> right;
@@ -21166,90 +21179,56 @@ namespace ts {
case SyntaxKind.MinusToken: return left - right;
case SyntaxKind.PercentToken: return left % right;
}
return undefined;
case SyntaxKind.NumericLiteral:
checkGrammarNumericLiteral(<NumericLiteral>e);
return +(<NumericLiteral>e).text;
case SyntaxKind.ParenthesizedExpression:
return evalConstant((<ParenthesizedExpression>e).expression);
case SyntaxKind.Identifier:
case SyntaxKind.ElementAccessExpression:
case SyntaxKind.PropertyAccessExpression:
const member = initializer.parent;
const currentType = getTypeOfSymbol(getSymbolOfNode(member.parent));
let enumType: Type;
let propertyName: string;
if (e.kind === SyntaxKind.Identifier) {
// unqualified names can refer to member that reside in different declaration of the enum so just doing name resolution won't work.
// instead pick current enum type and later try to fetch member from the type
enumType = currentType;
propertyName = (<Identifier>e).text;
}
break;
case SyntaxKind.StringLiteral:
return (<StringLiteral>expr).text;
case SyntaxKind.NumericLiteral:
checkGrammarNumericLiteral(<NumericLiteral>expr);
return +(<NumericLiteral>expr).text;
case SyntaxKind.ParenthesizedExpression:
return evaluate((<ParenthesizedExpression>expr).expression);
case SyntaxKind.Identifier:
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), (<Identifier>expr).text);
case SyntaxKind.ElementAccessExpression:
case SyntaxKind.PropertyAccessExpression:
if (isConstantMemberAccess(expr)) {
const type = getTypeOfExpression((<PropertyAccessExpression | ElementAccessExpression>expr).expression);
if (type.symbol && type.symbol.flags & SymbolFlags.Enum) {
const name = expr.kind === SyntaxKind.PropertyAccessExpression ?
(<PropertyAccessExpression>expr).name.text :
(<LiteralExpression>(<ElementAccessExpression>expr).argumentExpression).text;
return evaluateEnumMember(expr, type.symbol, name);
}
else {
let expression: Expression;
if (e.kind === SyntaxKind.ElementAccessExpression) {
if ((<ElementAccessExpression>e).argumentExpression === undefined ||
(<ElementAccessExpression>e).argumentExpression.kind !== SyntaxKind.StringLiteral) {
return undefined;
}
expression = (<ElementAccessExpression>e).expression;
propertyName = (<LiteralExpression>(<ElementAccessExpression>e).argumentExpression).text;
}
else {
expression = (<PropertyAccessExpression>e).expression;
propertyName = (<PropertyAccessExpression>e).name.text;
}
}
break;
}
return undefined;
}
// expression part in ElementAccess\PropertyAccess should be either identifier or dottedName
let current = expression;
while (current) {
if (current.kind === SyntaxKind.Identifier) {
break;
}
else if (current.kind === SyntaxKind.PropertyAccessExpression) {
current = (<ElementAccessExpression>current).expression;
}
else {
return undefined;
}
}
enumType = getTypeOfExpression(expression);
// allow references to constant members of other enums
if (!(enumType.symbol && (enumType.symbol.flags & SymbolFlags.Enum))) {
return undefined;
}
}
if (propertyName === undefined) {
return undefined;
}
const property = getPropertyOfObjectType(enumType, propertyName);
if (!property || !(property.flags & SymbolFlags.EnumMember)) {
return undefined;
}
const propertyDecl = property.valueDeclaration;
// self references are illegal
if (member === propertyDecl) {
return undefined;
}
// illegal case: forward reference
if (!isBlockScopedNameDeclaredBeforeUse(propertyDecl, member)) {
reportError = false;
error(e, Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
return undefined;
}
return <number>getNodeLinks(propertyDecl).enumMemberValue;
function evaluateEnumMember(expr: Expression, enumSymbol: Symbol, name: string) {
const memberSymbol = enumSymbol.exports.get(name);
if (memberSymbol) {
const declaration = memberSymbol.valueDeclaration;
if (declaration !== member) {
if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
return getNodeLinks(declaration).enumMemberValue;
}
error(expr, Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
return 0;
}
}
return undefined;
}
}
function isConstantMemberAccess(node: Expression): boolean {
return node.kind === SyntaxKind.Identifier ||
node.kind === SyntaxKind.PropertyAccessExpression && isConstantMemberAccess((<PropertyAccessExpression>node).expression) ||
node.kind === SyntaxKind.ElementAccessExpression && isConstantMemberAccess((<ElementAccessExpression>node).expression) &&
(<ElementAccessExpression>node).argumentExpression.kind === SyntaxKind.StringLiteral;
}
function checkEnumDeclaration(node: EnumDeclaration) {
if (!produceDiagnostics) {
return;
@@ -22915,7 +22894,7 @@ namespace ts {
return getNodeLinks(node).flags;
}
function getEnumMemberValue(node: EnumMember): number {
function getEnumMemberValue(node: EnumMember): string | number {
computeEnumMemberValues(<EnumDeclaration>node.parent);
return getNodeLinks(node).enumMemberValue;
}
@@ -22930,7 +22909,7 @@ namespace ts {
return false;
}
function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number {
function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number {
if (node.kind === SyntaxKind.EnumMember) {
return getEnumMemberValue(<EnumMember>node);
}
@@ -23015,7 +22994,7 @@ namespace ts {
? getWidenedLiteralType(getTypeOfSymbol(symbol))
: unknownType;
if (flags & TypeFormatFlags.AddUndefined) {
type = includeFalsyTypes(type, TypeFlags.Undefined);
type = getNullableType(type, TypeFlags.Undefined);
}
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
}
+1 -1
View File
@@ -984,7 +984,7 @@ namespace ts {
const enumMemberValue = resolver.getConstantValue(node);
if (enumMemberValue !== undefined) {
write(" = ");
write(enumMemberValue.toString());
write(getTextOfConstantValue(enumMemberValue));
}
write(",");
writeLine();
+4
View File
@@ -1855,6 +1855,10 @@
"category": "Error",
"code": 2552
},
"Computed values are not permitted in an enum with string valued members.": {
"category": "Error",
"code": 2553
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
+1 -1
View File
@@ -1154,7 +1154,7 @@ namespace ts {
// check if constant enum value is integer
const constantValue = getConstantValue(expression);
// isFinite handles cases when constantValue is undefined
return isFinite(constantValue)
return typeof constantValue === "number" && isFinite(constantValue)
&& Math.floor(constantValue) === constantValue
&& printerOptions.removeComments;
}
+1 -1
View File
@@ -2371,7 +2371,7 @@ namespace ts {
/**
* Sets the constant value to emit for an expression.
*/
export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: number) {
export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: string | number) {
const emitNode = getOrCreateEmitNode(node);
emitNode.constantValue = value;
return node;
+19 -14
View File
@@ -2494,22 +2494,27 @@ namespace ts {
// we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
// old emitter always generate 'expression' part of the name as-is.
const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
const valueExpression = transformEnumMemberDeclarationValue(member);
const innerAssignment = createAssignment(
createElementAccess(
currentNamespaceContainerName,
name
),
valueExpression
);
const outerAssignment = valueExpression.kind === SyntaxKind.StringLiteral ?
innerAssignment :
createAssignment(
createElementAccess(
currentNamespaceContainerName,
innerAssignment
),
name
);
return setTextRange(
createStatement(
setTextRange(
createAssignment(
createElementAccess(
currentNamespaceContainerName,
createAssignment(
createElementAccess(
currentNamespaceContainerName,
name
),
transformEnumMemberDeclarationValue(member)
)
),
name
),
outerAssignment,
member
)
),
@@ -3349,7 +3354,7 @@ namespace ts {
return node;
}
function tryGetConstEnumValue(node: Node): number {
function tryGetConstEnumValue(node: Node): string | number {
if (compilerOptions.isolatedModules) {
return undefined;
}
+24 -15
View File
@@ -2551,7 +2551,7 @@ namespace ts {
isUnknownSymbol(symbol: Symbol): boolean;
/* @internal */ getMergedSymbol(symbol: Symbol): Symbol;
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number | undefined;
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
/** Follow all aliases to get the original symbol. */
getAliasedSymbol(symbol: Symbol): Symbol;
@@ -2776,7 +2776,7 @@ namespace ts {
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult;
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number;
getReferencedValueDeclaration(reference: Identifier): Declaration;
getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind;
isOptionalParameter(node: ParameterDeclaration): boolean;
@@ -2914,6 +2914,13 @@ namespace ts {
isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration
bindingElement?: BindingElement; // Binding element associated with property symbol
exportsSomeValue?: boolean; // True if module exports some value (not just types)
enumKind?: EnumKind; // Enum declaration classification
}
/* @internal */
export const enum EnumKind {
Numeric, // Numeric enum (each member has a TypeFlags.Enum type)
Literal // Literal enum (each member has a TypeFlags.EnumLiteral type)
}
/* @internal */
@@ -2986,7 +2993,7 @@ namespace ts {
resolvedSymbol?: Symbol; // Cached name resolution result
resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result
maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate
enumMemberValue?: number; // Constant value of enum member
enumMemberValue?: string | number; // Constant value of enum member
isVisible?: boolean; // Is this node visible
containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
@@ -3006,7 +3013,7 @@ namespace ts {
StringLiteral = 1 << 5,
NumberLiteral = 1 << 6,
BooleanLiteral = 1 << 7,
EnumLiteral = 1 << 8,
EnumLiteral = 1 << 8, // Always combined with StringLiteral, NumberLiteral, or Union
ESSymbol = 1 << 9, // Type of symbol primitive introduced in ES6
Void = 1 << 10,
Undefined = 1 << 11,
@@ -3032,7 +3039,7 @@ namespace ts {
/* @internal */
Nullable = Undefined | Null,
Literal = StringLiteral | NumberLiteral | BooleanLiteral | EnumLiteral,
Literal = StringLiteral | NumberLiteral | BooleanLiteral,
StringOrNumberLiteral = StringLiteral | NumberLiteral,
/* @internal */
DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null,
@@ -3040,9 +3047,9 @@ namespace ts {
/* @internal */
Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
/* @internal */
Primitive = String | Number | Boolean | Enum | ESSymbol | Void | Undefined | Null | Literal,
Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal,
StringLike = String | StringLiteral | Index,
NumberLike = Number | NumberLiteral | Enum | EnumLiteral,
NumberLike = Number | NumberLiteral | Enum,
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
UnionOrIntersection = Union | Intersection,
@@ -3081,19 +3088,21 @@ namespace ts {
// String literal types (TypeFlags.StringLiteral)
// Numeric literal types (TypeFlags.NumberLiteral)
export interface LiteralType extends Type {
text: string; // Text of literal
value: string | number; // Value of literal
freshType?: LiteralType; // Fresh version of type
regularType?: LiteralType; // Regular version of type
}
// Enum types (TypeFlags.Enum)
export interface EnumType extends Type {
memberTypes: EnumLiteralType[];
export interface StringLiteralType extends LiteralType {
value: string;
}
// Enum types (TypeFlags.EnumLiteral)
export interface EnumLiteralType extends LiteralType {
baseType: EnumType & UnionType; // Base enum type
export interface NumberLiteralType extends LiteralType {
value: number;
}
// Enum types (TypeFlags.Enum)
export interface EnumType extends Type {
}
export const enum ObjectFlags {
@@ -3961,7 +3970,7 @@ namespace ts {
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
sourceMapRange?: TextRange; // The text range to use when emitting leading or trailing source mappings
tokenSourceMapRanges?: TextRange[]; // The text range to use when emitting source mappings for tokens
constantValue?: number; // The constant value of an expression
constantValue?: string | number; // The constant value of an expression
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
helpers?: EmitHelper[]; // Emit helpers for the node
}
+4
View File
@@ -350,6 +350,10 @@ namespace ts {
Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
}
export function getTextOfConstantValue(value: string | number) {
return typeof value === "string" ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
}
// Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
export function escapeIdentifier(identifier: string): string {
return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;
+1 -1
View File
@@ -275,7 +275,7 @@ namespace ts.Completions {
}
}
else if (type.flags & TypeFlags.StringLiteral) {
const name = (<LiteralType>type).text;
const name = (<StringLiteralType>type).value;
if (!uniques.has(name)) {
uniques.set(name, true);
result.push({
+2 -1
View File
@@ -336,7 +336,8 @@ namespace ts.SymbolDisplay {
displayParts.push(spacePart());
displayParts.push(operatorPart(SyntaxKind.EqualsToken));
displayParts.push(spacePart());
displayParts.push(displayPart(constantValue.toString(), SymbolDisplayPartKind.numericLiteral));
displayParts.push(displayPart(getTextOfConstantValue(constantValue),
typeof constantValue === "number" ? SymbolDisplayPartKind.numericLiteral : SymbolDisplayPartKind.stringLiteral));
}
}
}
@@ -98,8 +98,8 @@ var e3 = t3[2]; // any
>2 : 2
var e4 = t4[3]; // number
>e4 : number | E1 | E2
>t4[3] : number | E1 | E2
>e4 : number
>t4[3] : number
>t4 : [E1, E2, number]
>3 : 3
@@ -12,7 +12,7 @@ var o = {
>{ [E1.x || E2.x]: 0} : { [x: number]: number; }
[E1.x || E2.x]: 0
>E1.x || E2.x : E1 | E2
>E1.x || E2.x : E2
>E1.x : E1
>E1 : typeof E1
>x : E1
@@ -12,7 +12,7 @@ var o = {
>{ [E1.x || E2.x]: 0} : { [x: number]: number; }
[E1.x || E2.x]: 0
>E1.x || E2.x : E1 | E2
>E1.x || E2.x : E2
>E1.x : E1
>E1 : typeof E1
>x : E1
@@ -1,15 +1,19 @@
tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2324: Property 'd' is missing in type 'First.E'.
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(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(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(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(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(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 (11 errors) ====
@@ -82,7 +86,8 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2324: Property 'd'
abc = secondAbc; // ok
abc = secondAbcd; // missing 'd'
~~~
!!! error TS2324: Property 'd' is missing in type 'First.E'.
!!! error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'.
!!! error TS2322: Property 'd' is missing in type 'First.E'.
abc = secondAb; // ok
abc = secondCd; // missing 'd'
~~~
@@ -98,10 +103,12 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2324: Property 'd'
secondAbcd = abc; // ok
secondAb = abc; // missing 'c'
~~~~~~~~
!!! error TS2324: Property 'c' is missing in type 'Ab.E'.
!!! error TS2322: Type 'First.E' is not assignable to type 'Ab.E'.
!!! error TS2322: 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'.
@@ -121,7 +128,8 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2324: Property 'd'
// merged enums compare all their members
abc = merged; // missing 'd'
~~~
!!! error TS2324: Property 'd' is missing in type 'First.E'.
!!! error TS2322: Type 'Merged.E' is not assignable to type 'First.E'.
!!! error TS2322: Property 'd' is missing in type 'First.E'.
merged = abc; // ok
abc = merged2; // ok
merged2 = abc; // ok
@@ -1,86 +0,0 @@
tests/cases/conformance/enums/enumBasics.ts(13,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'e' must be of type 'typeof E1', but here has type '{ readonly [n: number]: string; readonly A: E1; readonly B: E1; readonly C: E1; }'.
==== tests/cases/conformance/enums/enumBasics.ts (1 errors) ====
// Enum without initializers have first member = 0 and successive members = N + 1
enum E1 {
A,
B,
C
}
// Enum type is a subtype of Number
var x: number = E1.A;
// Enum object type is anonymous with properties of the enum type and numeric indexer
var e = E1;
var e: {
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'e' must be of type 'typeof E1', but here has type '{ readonly [n: number]: string; readonly A: E1; readonly B: E1; readonly C: E1; }'.
readonly A: E1;
readonly B: E1;
readonly C: E1;
readonly [n: number]: string;
};
var e: typeof E1;
// Reverse mapping of enum returns string name of property
var s = E1[e.A];
var s: string;
// Enum with only constant members
enum E2 {
A = 1, B = 2, C = 3
}
// Enum with only computed members
enum E3 {
X = 'foo'.length, Y = 4 + 3, Z = +'foo'
}
// Enum with constant members followed by computed members
enum E4 {
X = 0, Y, Z = 'foo'.length
}
// Enum with > 2 constant members with no initializer for first member, non zero initializer for second element
enum E5 {
A,
B = 3,
C // 4
}
enum E6 {
A,
B = 0,
C // 1
}
// Enum with computed member initializer of type 'any'
enum E7 {
A = 'foo'['foo']
}
// Enum with computed member initializer of type number
enum E8 {
B = 'foo'['foo']
}
//Enum with computed member intializer of same enum type
enum E9 {
A,
B = A
}
// (refer to .js to validate)
// Enum constant members are propagated
var doNotPropagate = [
E8.B, E7.A, E4.Z, E3.X, E3.Y, E3.Z
];
// Enum computed members are not propagated
var doPropagate = [
E9.A, E9.B, E6.B, E6.C, E6.A, E5.A, E5.B, E5.C
];
+3 -3
View File
@@ -12,9 +12,9 @@ var x: number = E1.A;
// Enum object type is anonymous with properties of the enum type and numeric indexer
var e = E1;
var e: {
readonly A: E1;
readonly B: E1;
readonly C: E1;
readonly A: E1.A;
readonly B: E1.B;
readonly C: E1.C;
readonly [n: number]: string;
};
var e: typeof E1;
+8 -5
View File
@@ -28,17 +28,20 @@ var e = E1;
var e: {
>e : Symbol(e, Decl(enumBasics.ts, 11, 3), Decl(enumBasics.ts, 12, 3), Decl(enumBasics.ts, 18, 3))
readonly A: E1;
readonly A: E1.A;
>A : Symbol(A, Decl(enumBasics.ts, 12, 8))
>E1 : Symbol(E1, Decl(enumBasics.ts, 0, 0))
>A : Symbol(E1.A, Decl(enumBasics.ts, 1, 9))
readonly B: E1;
>B : Symbol(B, Decl(enumBasics.ts, 13, 19))
readonly B: E1.B;
>B : Symbol(B, Decl(enumBasics.ts, 13, 21))
>E1 : Symbol(E1, Decl(enumBasics.ts, 0, 0))
>B : Symbol(E1.B, Decl(enumBasics.ts, 2, 6))
readonly C: E1;
>C : Symbol(C, Decl(enumBasics.ts, 14, 19))
readonly C: E1.C;
>C : Symbol(C, Decl(enumBasics.ts, 14, 21))
>E1 : Symbol(E1, Decl(enumBasics.ts, 0, 0))
>C : Symbol(E1.C, Decl(enumBasics.ts, 3, 6))
readonly [n: number]: string;
>n : Symbol(n, Decl(enumBasics.ts, 16, 14))
+57 -54
View File
@@ -4,21 +4,21 @@ enum E1 {
>E1 : E1
A,
>A : E1
>A : E1.A
B,
>B : E1
>B : E1.B
C
>C : E1
>C : E1.C
}
// Enum type is a subtype of Number
var x: number = E1.A;
>x : number
>E1.A : E1
>E1.A : E1.A
>E1 : typeof E1
>A : E1
>A : E1.A
// Enum object type is anonymous with properties of the enum type and numeric indexer
var e = E1;
@@ -28,17 +28,20 @@ var e = E1;
var e: {
>e : typeof E1
readonly A: E1;
>A : E1
>E1 : E1
readonly A: E1.A;
>A : E1.A
>E1 : any
>A : E1.A
readonly B: E1;
>B : E1
>E1 : E1
readonly B: E1.B;
>B : E1.B
>E1 : any
>B : E1.B
readonly C: E1;
>C : E1
>E1 : E1
readonly C: E1.C;
>C : E1.C
>E1 : any
>C : E1.C
readonly [n: number]: string;
>n : number
@@ -53,9 +56,9 @@ var s = E1[e.A];
>s : string
>E1[e.A] : string
>E1 : typeof E1
>e.A : E1
>e.A : E1.A
>e : typeof E1
>A : E1
>A : E1.A
var s: string;
>s : string
@@ -66,12 +69,12 @@ enum E2 {
>E2 : E2
A = 1, B = 2, C = 3
>A : E2
>1 : number
>B : E2
>2 : number
>C : E2
>3 : number
>A : E2.A
>1 : 1
>B : E2.B
>2 : 2
>C : E2.C
>3 : 3
}
// Enum with only computed members
@@ -81,15 +84,15 @@ enum E3 {
X = 'foo'.length, Y = 4 + 3, Z = +'foo'
>X : E3
>'foo'.length : number
>'foo' : string
>'foo' : "foo"
>length : number
>Y : E3
>4 + 3 : number
>4 : number
>3 : number
>4 : 4
>3 : 3
>Z : E3
>+'foo' : number
>'foo' : string
>'foo' : "foo"
}
// Enum with constant members followed by computed members
@@ -98,11 +101,11 @@ enum E4 {
X = 0, Y, Z = 'foo'.length
>X : E4
>0 : number
>0 : 0
>Y : E4
>Z : E4
>'foo'.length : number
>'foo' : string
>'foo' : "foo"
>length : number
}
@@ -111,28 +114,28 @@ enum E5 {
>E5 : E5
A,
>A : E5
>A : E5.A
B = 3,
>B : E5
>3 : number
>B : E5.B
>3 : 3
C // 4
>C : E5
>C : E5.C
}
enum E6 {
>E6 : E6
A,
>A : E6
>A : E6.A
B = 0,
>B : E6
>0 : number
>B : E6.A
>0 : 0
C // 1
>C : E6
>C : E6.C
}
// Enum with computed member initializer of type 'any'
@@ -142,8 +145,8 @@ enum E7 {
A = 'foo'['foo']
>A : E7
>'foo'['foo'] : any
>'foo' : string
>'foo' : string
>'foo' : "foo"
>'foo' : "foo"
}
// Enum with computed member initializer of type number
@@ -153,8 +156,8 @@ enum E8 {
B = 'foo'['foo']
>B : E8
>'foo'['foo'] : any
>'foo' : string
>'foo' : string
>'foo' : "foo"
>'foo' : "foo"
}
//Enum with computed member intializer of same enum type
@@ -198,8 +201,8 @@ var doNotPropagate = [
];
// Enum computed members are not propagated
var doPropagate = [
>doPropagate : (E5 | E6 | E9)[]
>[ E9.A, E9.B, E6.B, E6.C, E6.A, E5.A, E5.B, E5.C] : (E5 | E6 | E9)[]
>doPropagate : (E9 | E6 | E5)[]
>[ E9.A, E9.B, E6.B, E6.C, E6.A, E5.A, E5.B, E5.C] : (E9 | E6 | E5)[]
E9.A, E9.B, E6.B, E6.C, E6.A, E5.A, E5.B, E5.C
>E9.A : E9
@@ -208,24 +211,24 @@ var doPropagate = [
>E9.B : E9
>E9 : typeof E9
>B : E9
>E6.B : E6
>E6.B : E6.A
>E6 : typeof E6
>B : E6
>E6.C : E6
>B : E6.A
>E6.C : E6.C
>E6 : typeof E6
>C : E6
>E6.A : E6
>C : E6.C
>E6.A : E6.A
>E6 : typeof E6
>A : E6
>E5.A : E5
>A : E6.A
>E5.A : E5.A
>E5 : typeof E5
>A : E5
>E5.B : E5
>A : E5.A
>E5.B : E5.B
>E5 : typeof E5
>B : E5
>E5.C : E5
>B : E5.B
>E5.C : E5.C
>E5 : typeof E5
>C : E5
>C : E5.C
];
@@ -0,0 +1,218 @@
//// [enumClassification.ts]
// An enum type where each member has no initializer or an initializer that specififes
// a numeric literal, a string literal, or a single identifier naming another member in
// the enum type is classified as a literal enum type. An enum type that doesn't adhere
// to this pattern is classified as a numeric enum type.
// Examples of literal enum types
enum E01 {
A
}
enum E02 {
A = 123
}
enum E03 {
A = "hello"
}
enum E04 {
A,
B,
C
}
enum E05 {
A,
B = 10,
C
}
enum E06 {
A = "one",
B = "two",
C = "three"
}
enum E07 {
A,
B,
C = "hi",
D = 10,
E,
F = "bye"
}
enum E08 {
A = 10,
B = "hello",
C = A,
D = B,
E = C,
}
// Examples of numeric enum types with only constant members
enum E10 {}
enum E11 {
A = +0,
B,
C
}
enum E12 {
A = 1 << 0,
B = 1 << 1,
C = 1 << 2
}
// Examples of numeric enum types with constant and computed members
enum E20 {
A = "foo".length,
B = A + 1,
C = +"123",
D = Math.sin(1)
}
//// [enumClassification.js]
// An enum type where each member has no initializer or an initializer that specififes
// a numeric literal, a string literal, or a single identifier naming another member in
// the enum type is classified as a literal enum type. An enum type that doesn't adhere
// to this pattern is classified as a numeric enum type.
// Examples of literal enum types
var E01;
(function (E01) {
E01[E01["A"] = 0] = "A";
})(E01 || (E01 = {}));
var E02;
(function (E02) {
E02[E02["A"] = 123] = "A";
})(E02 || (E02 = {}));
var E03;
(function (E03) {
E03["A"] = "hello";
})(E03 || (E03 = {}));
var E04;
(function (E04) {
E04[E04["A"] = 0] = "A";
E04[E04["B"] = 1] = "B";
E04[E04["C"] = 2] = "C";
})(E04 || (E04 = {}));
var E05;
(function (E05) {
E05[E05["A"] = 0] = "A";
E05[E05["B"] = 10] = "B";
E05[E05["C"] = 11] = "C";
})(E05 || (E05 = {}));
var E06;
(function (E06) {
E06["A"] = "one";
E06["B"] = "two";
E06["C"] = "three";
})(E06 || (E06 = {}));
var E07;
(function (E07) {
E07[E07["A"] = 0] = "A";
E07[E07["B"] = 1] = "B";
E07["C"] = "hi";
E07[E07["D"] = 10] = "D";
E07[E07["E"] = 11] = "E";
E07["F"] = "bye";
})(E07 || (E07 = {}));
var E08;
(function (E08) {
E08[E08["A"] = 10] = "A";
E08["B"] = "hello";
E08[E08["C"] = 10] = "C";
E08["D"] = "hello";
E08[E08["E"] = 10] = "E";
})(E08 || (E08 = {}));
// Examples of numeric enum types with only constant members
var E10;
(function (E10) {
})(E10 || (E10 = {}));
var E11;
(function (E11) {
E11[E11["A"] = 0] = "A";
E11[E11["B"] = 1] = "B";
E11[E11["C"] = 2] = "C";
})(E11 || (E11 = {}));
var E12;
(function (E12) {
E12[E12["A"] = 1] = "A";
E12[E12["B"] = 2] = "B";
E12[E12["C"] = 4] = "C";
})(E12 || (E12 = {}));
// Examples of numeric enum types with constant and computed members
var E20;
(function (E20) {
E20[E20["A"] = "foo".length] = "A";
E20[E20["B"] = E20.A + 1] = "B";
E20[E20["C"] = +"123"] = "C";
E20[E20["D"] = Math.sin(1)] = "D";
})(E20 || (E20 = {}));
//// [enumClassification.d.ts]
declare enum E01 {
A = 0,
}
declare enum E02 {
A = 123,
}
declare enum E03 {
A = "hello",
}
declare enum E04 {
A = 0,
B = 1,
C = 2,
}
declare enum E05 {
A = 0,
B = 10,
C = 11,
}
declare enum E06 {
A = "one",
B = "two",
C = "three",
}
declare enum E07 {
A = 0,
B = 1,
C = "hi",
D = 10,
E = 11,
F = "bye",
}
declare enum E08 {
A = 10,
B = "hello",
C = 10,
D = "hello",
E = 10,
}
declare enum E10 {
}
declare enum E11 {
A = 0,
B = 1,
C = 2,
}
declare enum E12 {
A = 1,
B = 2,
C = 4,
}
declare enum E20 {
A,
B,
C,
D,
}
@@ -0,0 +1,167 @@
=== tests/cases/conformance/enums/enumClassification.ts ===
// An enum type where each member has no initializer or an initializer that specififes
// a numeric literal, a string literal, or a single identifier naming another member in
// the enum type is classified as a literal enum type. An enum type that doesn't adhere
// to this pattern is classified as a numeric enum type.
// Examples of literal enum types
enum E01 {
>E01 : Symbol(E01, Decl(enumClassification.ts, 0, 0))
A
>A : Symbol(E01.A, Decl(enumClassification.ts, 7, 10))
}
enum E02 {
>E02 : Symbol(E02, Decl(enumClassification.ts, 9, 1))
A = 123
>A : Symbol(E02.A, Decl(enumClassification.ts, 11, 10))
}
enum E03 {
>E03 : Symbol(E03, Decl(enumClassification.ts, 13, 1))
A = "hello"
>A : Symbol(E03.A, Decl(enumClassification.ts, 15, 10))
}
enum E04 {
>E04 : Symbol(E04, Decl(enumClassification.ts, 17, 1))
A,
>A : Symbol(E04.A, Decl(enumClassification.ts, 19, 10))
B,
>B : Symbol(E04.B, Decl(enumClassification.ts, 20, 6))
C
>C : Symbol(E04.C, Decl(enumClassification.ts, 21, 6))
}
enum E05 {
>E05 : Symbol(E05, Decl(enumClassification.ts, 23, 1))
A,
>A : Symbol(E05.A, Decl(enumClassification.ts, 25, 10))
B = 10,
>B : Symbol(E05.B, Decl(enumClassification.ts, 26, 6))
C
>C : Symbol(E05.C, Decl(enumClassification.ts, 27, 11))
}
enum E06 {
>E06 : Symbol(E06, Decl(enumClassification.ts, 29, 1))
A = "one",
>A : Symbol(E06.A, Decl(enumClassification.ts, 31, 10))
B = "two",
>B : Symbol(E06.B, Decl(enumClassification.ts, 32, 14))
C = "three"
>C : Symbol(E06.C, Decl(enumClassification.ts, 33, 14))
}
enum E07 {
>E07 : Symbol(E07, Decl(enumClassification.ts, 35, 1))
A,
>A : Symbol(E07.A, Decl(enumClassification.ts, 37, 10))
B,
>B : Symbol(E07.B, Decl(enumClassification.ts, 38, 6))
C = "hi",
>C : Symbol(E07.C, Decl(enumClassification.ts, 39, 6))
D = 10,
>D : Symbol(E07.D, Decl(enumClassification.ts, 40, 13))
E,
>E : Symbol(E07.E, Decl(enumClassification.ts, 41, 11))
F = "bye"
>F : Symbol(E07.F, Decl(enumClassification.ts, 42, 6))
}
enum E08 {
>E08 : Symbol(E08, Decl(enumClassification.ts, 44, 1))
A = 10,
>A : Symbol(E08.A, Decl(enumClassification.ts, 46, 10))
B = "hello",
>B : Symbol(E08.B, Decl(enumClassification.ts, 47, 11))
C = A,
>C : Symbol(E08.C, Decl(enumClassification.ts, 48, 16))
>A : Symbol(E08.A, Decl(enumClassification.ts, 46, 10))
D = B,
>D : Symbol(E08.D, Decl(enumClassification.ts, 49, 10))
>B : Symbol(E08.B, Decl(enumClassification.ts, 47, 11))
E = C,
>E : Symbol(E08.E, Decl(enumClassification.ts, 50, 10))
>C : Symbol(E08.C, Decl(enumClassification.ts, 48, 16))
}
// Examples of numeric enum types with only constant members
enum E10 {}
>E10 : Symbol(E10, Decl(enumClassification.ts, 52, 1))
enum E11 {
>E11 : Symbol(E11, Decl(enumClassification.ts, 56, 11))
A = +0,
>A : Symbol(E11.A, Decl(enumClassification.ts, 58, 10))
B,
>B : Symbol(E11.B, Decl(enumClassification.ts, 59, 11))
C
>C : Symbol(E11.C, Decl(enumClassification.ts, 60, 6))
}
enum E12 {
>E12 : Symbol(E12, Decl(enumClassification.ts, 62, 1))
A = 1 << 0,
>A : Symbol(E12.A, Decl(enumClassification.ts, 64, 10))
B = 1 << 1,
>B : Symbol(E12.B, Decl(enumClassification.ts, 65, 15))
C = 1 << 2
>C : Symbol(E12.C, Decl(enumClassification.ts, 66, 15))
}
// Examples of numeric enum types with constant and computed members
enum E20 {
>E20 : Symbol(E20, Decl(enumClassification.ts, 68, 1))
A = "foo".length,
>A : Symbol(E20.A, Decl(enumClassification.ts, 72, 10))
>"foo".length : Symbol(String.length, Decl(lib.d.ts, --, --))
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
B = A + 1,
>B : Symbol(E20.B, Decl(enumClassification.ts, 73, 21))
>A : Symbol(E20.A, Decl(enumClassification.ts, 72, 10))
C = +"123",
>C : Symbol(E20.C, Decl(enumClassification.ts, 74, 14))
D = Math.sin(1)
>D : Symbol(E20.D, Decl(enumClassification.ts, 75, 15))
>Math.sin : Symbol(Math.sin, Decl(lib.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>sin : Symbol(Math.sin, Decl(lib.d.ts, --, --))
}
@@ -0,0 +1,196 @@
=== tests/cases/conformance/enums/enumClassification.ts ===
// An enum type where each member has no initializer or an initializer that specififes
// a numeric literal, a string literal, or a single identifier naming another member in
// the enum type is classified as a literal enum type. An enum type that doesn't adhere
// to this pattern is classified as a numeric enum type.
// Examples of literal enum types
enum E01 {
>E01 : E01
A
>A : E01
}
enum E02 {
>E02 : E02
A = 123
>A : E02
>123 : 123
}
enum E03 {
>E03 : E03
A = "hello"
>A : E03
>"hello" : "hello"
}
enum E04 {
>E04 : E04
A,
>A : E04.A
B,
>B : E04.B
C
>C : E04.C
}
enum E05 {
>E05 : E05
A,
>A : E05.A
B = 10,
>B : E05.B
>10 : 10
C
>C : E05.C
}
enum E06 {
>E06 : E06
A = "one",
>A : E06.A
>"one" : "one"
B = "two",
>B : E06.B
>"two" : "two"
C = "three"
>C : E06.C
>"three" : "three"
}
enum E07 {
>E07 : E07
A,
>A : E07.A
B,
>B : E07.B
C = "hi",
>C : E07.C
>"hi" : "hi"
D = 10,
>D : E07.D
>10 : 10
E,
>E : E07.E
F = "bye"
>F : E07.F
>"bye" : "bye"
}
enum E08 {
>E08 : E08
A = 10,
>A : E08.A
>10 : 10
B = "hello",
>B : E08.B
>"hello" : "hello"
C = A,
>C : E08.A
>A : E08.A
D = B,
>D : E08.B
>B : E08.B
E = C,
>E : E08.A
>C : E08.A
}
// Examples of numeric enum types with only constant members
enum E10 {}
>E10 : E10
enum E11 {
>E11 : E11
A = +0,
>A : E11
>+0 : number
>0 : 0
B,
>B : E11
C
>C : E11
}
enum E12 {
>E12 : E12
A = 1 << 0,
>A : E12
>1 << 0 : number
>1 : 1
>0 : 0
B = 1 << 1,
>B : E12
>1 << 1 : number
>1 : 1
>1 : 1
C = 1 << 2
>C : E12
>1 << 2 : number
>1 : 1
>2 : 2
}
// Examples of numeric enum types with constant and computed members
enum E20 {
>E20 : E20
A = "foo".length,
>A : E20
>"foo".length : number
>"foo" : "foo"
>length : number
B = A + 1,
>B : E20
>A + 1 : number
>A : E20
>1 : 1
C = +"123",
>C : E20
>+"123" : number
>"123" : "123"
D = Math.sin(1)
>D : E20
>Math.sin(1) : number
>Math.sin : (x: number) => number
>Math : Math
>sin : (x: number) => number
>1 : 1
}
@@ -3,13 +3,17 @@ tests/cases/conformance/enums/enumErrors.ts(3,6): error TS2431: Enum name cannot
tests/cases/conformance/enums/enumErrors.ts(4,6): error TS2431: Enum name cannot be 'string'.
tests/cases/conformance/enums/enumErrors.ts(5,6): error TS2431: Enum name cannot be 'boolean'.
tests/cases/conformance/enums/enumErrors.ts(9,9): error TS2322: Type 'Number' is not assignable to type 'E5'.
tests/cases/conformance/enums/enumErrors.ts(26,9): error TS2322: Type '""' is not assignable to type 'E11'.
tests/cases/conformance/enums/enumErrors.ts(26,9): error TS2322: Type 'true' is not assignable to type 'E11'.
tests/cases/conformance/enums/enumErrors.ts(27,9): error TS2322: Type 'Date' is not assignable to type 'E11'.
tests/cases/conformance/enums/enumErrors.ts(28,9): error TS2304: Cannot find name 'window'.
tests/cases/conformance/enums/enumErrors.ts(29,9): error TS2322: Type '{}' is not assignable to type 'E11'.
tests/cases/conformance/enums/enumErrors.ts(35,9): error TS2553: Computed values are not permitted in an enum with string valued members.
tests/cases/conformance/enums/enumErrors.ts(36,9): error TS2553: Computed values are not permitted in an enum with string valued members.
tests/cases/conformance/enums/enumErrors.ts(37,9): error TS2553: Computed values are not permitted in an enum with string valued members.
tests/cases/conformance/enums/enumErrors.ts(38,9): error TS2553: Computed values are not permitted in an enum with string valued members.
==== tests/cases/conformance/enums/enumErrors.ts (9 errors) ====
==== tests/cases/conformance/enums/enumErrors.ts (13 errors) ====
// Enum named with PredefinedTypes
enum any { }
~~~
@@ -45,9 +49,9 @@ tests/cases/conformance/enums/enumErrors.ts(29,9): error TS2322: Type '{}' is no
// Enum with computed member intializer of other types
enum E11 {
A = '',
~~
!!! error TS2322: Type '""' is not assignable to type 'E11'.
A = true,
~~~~
!!! error TS2322: Type 'true' is not assignable to type 'E11'.
B = new Date(),
~~~~~~~~~~
!!! error TS2322: Type 'Date' is not assignable to type 'E11'.
@@ -58,4 +62,21 @@ tests/cases/conformance/enums/enumErrors.ts(29,9): error TS2322: Type '{}' is no
~~
!!! error TS2322: Type '{}' is not assignable to type 'E11'.
}
// Enum with string valued member and computed member initializers
enum E12 {
A = '',
B = new Date(),
~~~~~~~~~~
!!! error TS2553: Computed values are not permitted in an enum with string valued members.
C = window,
~~~~~~
!!! error TS2553: Computed values are not permitted in an enum with string valued members.
D = {},
~~
!!! error TS2553: Computed values are not permitted in an enum with string valued members.
E = 1 + 1,
~~~~~
!!! error TS2553: Computed values are not permitted in an enum with string valued members.
}
+20 -2
View File
@@ -24,11 +24,20 @@ enum E10 {
// Enum with computed member intializer of other types
enum E11 {
A = '',
A = true,
B = new Date(),
C = window,
D = {}
}
// Enum with string valued member and computed member initializers
enum E12 {
A = '',
B = new Date(),
C = window,
D = {},
E = 1 + 1,
}
//// [enumErrors.js]
@@ -65,8 +74,17 @@ var E10;
// Enum with computed member intializer of other types
var E11;
(function (E11) {
E11[E11["A"] = ''] = "A";
E11[E11["A"] = true] = "A";
E11[E11["B"] = new Date()] = "B";
E11[E11["C"] = window] = "C";
E11[E11["D"] = {}] = "D";
})(E11 || (E11 = {}));
// Enum with string valued member and computed member initializers
var E12;
(function (E12) {
E12["A"] = "";
E12[E12["B"] = 0] = "B";
E12[E12["C"] = 0] = "C";
E12[E12["D"] = 0] = "D";
E12[E12["E"] = 0] = "E";
})(E12 || (E12 = {}));
@@ -19,11 +19,11 @@ var E1;
(function (E1) {
// illegal case
// forward reference to the element of the same enum
E1[E1["X"] = E1.Y] = "X";
E1[E1["X1"] = E1["Y"]] = "X1";
E1[E1["X"] = 0] = "X";
E1[E1["X1"] = 0] = "X1";
// forward reference to the element of the same enum
E1[E1["Y"] = E1.Z] = "Y";
E1[E1["Y1"] = E1["Z"]] = "Y1";
E1[E1["Y"] = 0] = "Y";
E1[E1["Y1"] = 0] = "Y1";
})(E1 || (E1 = {}));
(function (E1) {
E1[E1["Z"] = 4] = "Z";
@@ -290,7 +290,7 @@ function f3() {
>c2 : 1 | "two"
let x3 = c3;
>x3 : number | boolean | E
>x3 : number | boolean
>c3 : true | E.A | 123
let x4 = c4;
@@ -365,7 +365,7 @@ var rf5 = a5 && a6;
var rf6 = a6 && a6;
>rf6 : E
>a6 && a6 : E.b | E.c
>a6 && a6 : E
>a6 : E
>a6 : E.b | E.c
@@ -128,7 +128,7 @@ var rb5 = a5 || a2; // void || boolean is void | boolean
var rb6 = a6 || a2; // enum || boolean is E | boolean
>rb6 : boolean | E
>a6 || a2 : boolean | E
>a6 || a2 : boolean | E.b | E.c
>a6 : E
>a2 : boolean
@@ -248,7 +248,7 @@ var rd5 = a5 || a4; // void || string is void | string
var rd6 = a6 || a4; // enum || string is enum | string
>rd6 : string | E
>a6 || a4 : string | E
>a6 || a4 : string | E.b | E.c
>a6 : E
>a4 : string
@@ -308,7 +308,7 @@ var re5 = a5 || a5; // void || void is void
var re6 = a6 || a5; // enum || void is enum | void
>re6 : void | E
>a6 || a5 : void | E
>a6 || a5 : void | E.b | E.c
>a6 : E
>a5 : void
@@ -428,7 +428,7 @@ var rh5 = a5 || a7; // void || object is void | object
var rh6 = a6 || a7; // enum || object is enum | object
>rh6 : E | { a: string; }
>a6 || a7 : E | { a: string; }
>a6 || a7 : E.b | E.c | { a: string; }
>a6 : E
>a7 : { a: string; }
@@ -488,7 +488,7 @@ var ri5 = a5 || a8; // void || array is void | array
var ri6 = a6 || a8; // enum || array is enum | array
>ri6 : E | string[]
>a6 || a8 : E | string[]
>a6 || a8 : E.b | E.c | string[]
>a6 : E
>a8 : string[]
@@ -548,7 +548,7 @@ var rj5 = a5 || null; // void || null is void
var rj6 = a6 || null; // enum || null is E
>rj6 : E
>a6 || null : E
>a6 || null : E.b | E.c
>a6 : E
>null : null
@@ -608,7 +608,7 @@ var rf5 = a5 || undefined; // void || undefined is void
var rf6 = a6 || undefined; // enum || undefined is E
>rf6 : E
>a6 || undefined : E
>a6 || undefined : E.b | E.c
>a6 : E
>undefined : undefined
@@ -81,6 +81,6 @@ class D {
>PropDeco : (target: Object, propKey: string | symbol) => void
d: E | number;
>d : number | E
>d : number
>E : E
}
@@ -0,0 +1,178 @@
//// [stringEnumLiteralTypes1.ts]
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
type YesNo = Choice.Yes | Choice.No;
type NoYes = Choice.No | Choice.Yes;
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
function f1() {
var a: YesNo;
var a: NoYes;
var a: Choice.Yes | Choice.No;
var a: Choice.No | Choice.Yes;
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
b = a;
c = a;
c = b;
}
function f3(a: Choice.Yes, b: YesNo) {
var x = a + b;
var y = a == b;
var y = a != b;
var y = a === b;
var y = a !== b;
var y = a > b;
var y = a < b;
var y = a >= b;
var y = a <= b;
var y = !b;
}
declare function g(x: Choice.Yes): string;
declare function g(x: Choice.No): boolean;
declare function g(x: Choice): number;
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
var z1 = g(Choice.Yes);
var z2 = g(Choice.No);
var z3 = g(a);
var z4 = g(b);
var z5 = g(c);
}
function assertNever(x: never): never {
throw new Error("Unexpected value");
}
function f10(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
}
function f11(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
return assertNever(x);
}
function f12(x: UnknownYesNo) {
if (x) {
x;
}
else {
x;
}
}
function f13(x: UnknownYesNo) {
if (x === Choice.Yes) {
x;
}
else {
x;
}
}
type Item =
{ kind: Choice.Yes, a: string } |
{ kind: Choice.No, b: string };
function f20(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
}
function f21(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
return assertNever(x);
}
//// [stringEnumLiteralTypes1.js]
;
function f1() {
var a;
var a;
var a;
var a;
}
function f2(a, b, c) {
b = a;
c = a;
c = b;
}
function f3(a, b) {
var x = a + b;
var y = a == b;
var y = a != b;
var y = a === b;
var y = a !== b;
var y = a > b;
var y = a < b;
var y = a >= b;
var y = a <= b;
var y = !b;
}
function f5(a, b, c) {
var z1 = g("yes" /* Yes */);
var z2 = g("no" /* No */);
var z3 = g(a);
var z4 = g(b);
var z5 = g(c);
}
function assertNever(x) {
throw new Error("Unexpected value");
}
function f10(x) {
switch (x) {
case "yes" /* Yes */: return "true";
case "no" /* No */: return "false";
}
}
function f11(x) {
switch (x) {
case "yes" /* Yes */: return "true";
case "no" /* No */: return "false";
}
return assertNever(x);
}
function f12(x) {
if (x) {
x;
}
else {
x;
}
}
function f13(x) {
if (x === "yes" /* Yes */) {
x;
}
else {
x;
}
}
function f20(x) {
switch (x.kind) {
case "yes" /* Yes */: return x.a;
case "no" /* No */: return x.b;
}
}
function f21(x) {
switch (x.kind) {
case "yes" /* Yes */: return x.a;
case "no" /* No */: return x.b;
}
return assertNever(x);
}
@@ -0,0 +1,353 @@
=== tests/cases/conformance/types/literal/stringEnumLiteralTypes1.ts ===
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Unknown : Symbol(Choice.Unknown, Decl(stringEnumLiteralTypes1.ts, 0, 19))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
type YesNo = Choice.Yes | Choice.No;
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes1.ts, 0, 59))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
type NoYes = Choice.No | Choice.Yes;
>NoYes : Symbol(NoYes, Decl(stringEnumLiteralTypes1.ts, 2, 36))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes1.ts, 3, 36))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Unknown : Symbol(Choice.Unknown, Decl(stringEnumLiteralTypes1.ts, 0, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
function f1() {
>f1 : Symbol(f1, Decl(stringEnumLiteralTypes1.ts, 4, 60))
var a: YesNo;
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 7, 7), Decl(stringEnumLiteralTypes1.ts, 8, 7), Decl(stringEnumLiteralTypes1.ts, 9, 7), Decl(stringEnumLiteralTypes1.ts, 10, 7))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes1.ts, 0, 59))
var a: NoYes;
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 7, 7), Decl(stringEnumLiteralTypes1.ts, 8, 7), Decl(stringEnumLiteralTypes1.ts, 9, 7), Decl(stringEnumLiteralTypes1.ts, 10, 7))
>NoYes : Symbol(NoYes, Decl(stringEnumLiteralTypes1.ts, 2, 36))
var a: Choice.Yes | Choice.No;
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 7, 7), Decl(stringEnumLiteralTypes1.ts, 8, 7), Decl(stringEnumLiteralTypes1.ts, 9, 7), Decl(stringEnumLiteralTypes1.ts, 10, 7))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
var a: Choice.No | Choice.Yes;
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 7, 7), Decl(stringEnumLiteralTypes1.ts, 8, 7), Decl(stringEnumLiteralTypes1.ts, 9, 7), Decl(stringEnumLiteralTypes1.ts, 10, 7))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
>f2 : Symbol(f2, Decl(stringEnumLiteralTypes1.ts, 11, 1))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 13, 12))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes1.ts, 0, 59))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 13, 21))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes1.ts, 3, 36))
>c : Symbol(c, Decl(stringEnumLiteralTypes1.ts, 13, 38))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
b = a;
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 13, 21))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 13, 12))
c = a;
>c : Symbol(c, Decl(stringEnumLiteralTypes1.ts, 13, 38))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 13, 12))
c = b;
>c : Symbol(c, Decl(stringEnumLiteralTypes1.ts, 13, 38))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 13, 21))
}
function f3(a: Choice.Yes, b: YesNo) {
>f3 : Symbol(f3, Decl(stringEnumLiteralTypes1.ts, 17, 1))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes1.ts, 0, 59))
var x = a + b;
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 20, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a == b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a != b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a === b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a !== b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a > b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a < b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a >= b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = a <= b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
var y = !b;
>y : Symbol(y, Decl(stringEnumLiteralTypes1.ts, 21, 7), Decl(stringEnumLiteralTypes1.ts, 22, 7), Decl(stringEnumLiteralTypes1.ts, 23, 7), Decl(stringEnumLiteralTypes1.ts, 24, 7), Decl(stringEnumLiteralTypes1.ts, 25, 7), Decl(stringEnumLiteralTypes1.ts, 26, 7), Decl(stringEnumLiteralTypes1.ts, 27, 7), Decl(stringEnumLiteralTypes1.ts, 28, 7), Decl(stringEnumLiteralTypes1.ts, 29, 7))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 19, 26))
}
declare function g(x: Choice.Yes): string;
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 32, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
declare function g(x: Choice.No): boolean;
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 33, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
declare function g(x: Choice): number;
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 34, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
>f5 : Symbol(f5, Decl(stringEnumLiteralTypes1.ts, 34, 38))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 36, 12))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes1.ts, 0, 59))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 36, 21))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes1.ts, 3, 36))
>c : Symbol(c, Decl(stringEnumLiteralTypes1.ts, 36, 38))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
var z1 = g(Choice.Yes);
>z1 : Symbol(z1, Decl(stringEnumLiteralTypes1.ts, 37, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
var z2 = g(Choice.No);
>z2 : Symbol(z2, Decl(stringEnumLiteralTypes1.ts, 38, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
var z3 = g(a);
>z3 : Symbol(z3, Decl(stringEnumLiteralTypes1.ts, 39, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 36, 12))
var z4 = g(b);
>z4 : Symbol(z4, Decl(stringEnumLiteralTypes1.ts, 40, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 36, 21))
var z5 = g(c);
>z5 : Symbol(z5, Decl(stringEnumLiteralTypes1.ts, 41, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes1.ts, 30, 1), Decl(stringEnumLiteralTypes1.ts, 32, 42), Decl(stringEnumLiteralTypes1.ts, 33, 42))
>c : Symbol(c, Decl(stringEnumLiteralTypes1.ts, 36, 38))
}
function assertNever(x: never): never {
>assertNever : Symbol(assertNever, Decl(stringEnumLiteralTypes1.ts, 42, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 44, 21))
throw new Error("Unexpected value");
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
}
function f10(x: YesNo) {
>f10 : Symbol(f10, Decl(stringEnumLiteralTypes1.ts, 46, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 48, 13))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes1.ts, 0, 59))
switch (x) {
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 48, 13))
case Choice.Yes: return "true";
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
case Choice.No: return "false";
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
}
}
function f11(x: YesNo) {
>f11 : Symbol(f11, Decl(stringEnumLiteralTypes1.ts, 53, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 55, 13))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes1.ts, 0, 59))
switch (x) {
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 55, 13))
case Choice.Yes: return "true";
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
case Choice.No: return "false";
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
}
return assertNever(x);
>assertNever : Symbol(assertNever, Decl(stringEnumLiteralTypes1.ts, 42, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 55, 13))
}
function f12(x: UnknownYesNo) {
>f12 : Symbol(f12, Decl(stringEnumLiteralTypes1.ts, 61, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 63, 13))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes1.ts, 3, 36))
if (x) {
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 63, 13))
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 63, 13))
}
else {
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 63, 13))
}
}
function f13(x: UnknownYesNo) {
>f13 : Symbol(f13, Decl(stringEnumLiteralTypes1.ts, 70, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 72, 13))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes1.ts, 3, 36))
if (x === Choice.Yes) {
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 72, 13))
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 72, 13))
}
else {
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 72, 13))
}
}
type Item =
>Item : Symbol(Item, Decl(stringEnumLiteralTypes1.ts, 79, 1))
{ kind: Choice.Yes, a: string } |
>kind : Symbol(kind, Decl(stringEnumLiteralTypes1.ts, 82, 5))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 82, 23))
{ kind: Choice.No, b: string };
>kind : Symbol(kind, Decl(stringEnumLiteralTypes1.ts, 83, 5))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 83, 22))
function f20(x: Item) {
>f20 : Symbol(f20, Decl(stringEnumLiteralTypes1.ts, 83, 35))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 85, 13))
>Item : Symbol(Item, Decl(stringEnumLiteralTypes1.ts, 79, 1))
switch (x.kind) {
>x.kind : Symbol(kind, Decl(stringEnumLiteralTypes1.ts, 82, 5), Decl(stringEnumLiteralTypes1.ts, 83, 5))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 85, 13))
>kind : Symbol(kind, Decl(stringEnumLiteralTypes1.ts, 82, 5), Decl(stringEnumLiteralTypes1.ts, 83, 5))
case Choice.Yes: return x.a;
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>x.a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 82, 23))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 85, 13))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 82, 23))
case Choice.No: return x.b;
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>x.b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 83, 22))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 85, 13))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 83, 22))
}
}
function f21(x: Item) {
>f21 : Symbol(f21, Decl(stringEnumLiteralTypes1.ts, 90, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 92, 13))
>Item : Symbol(Item, Decl(stringEnumLiteralTypes1.ts, 79, 1))
switch (x.kind) {
>x.kind : Symbol(kind, Decl(stringEnumLiteralTypes1.ts, 82, 5), Decl(stringEnumLiteralTypes1.ts, 83, 5))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 92, 13))
>kind : Symbol(kind, Decl(stringEnumLiteralTypes1.ts, 82, 5), Decl(stringEnumLiteralTypes1.ts, 83, 5))
case Choice.Yes: return x.a;
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes1.ts, 0, 33))
>x.a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 82, 23))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 92, 13))
>a : Symbol(a, Decl(stringEnumLiteralTypes1.ts, 82, 23))
case Choice.No: return x.b;
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes1.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes1.ts, 0, 46))
>x.b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 83, 22))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 92, 13))
>b : Symbol(b, Decl(stringEnumLiteralTypes1.ts, 83, 22))
}
return assertNever(x);
>assertNever : Symbol(assertNever, Decl(stringEnumLiteralTypes1.ts, 42, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes1.ts, 92, 13))
}
@@ -0,0 +1,383 @@
=== tests/cases/conformance/types/literal/stringEnumLiteralTypes1.ts ===
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
>Choice : Choice
>Unknown : Choice.Unknown
>"" : ""
>Yes : Choice.Yes
>"yes" : "yes"
>No : Choice.No
>"no" : "no"
type YesNo = Choice.Yes | Choice.No;
>YesNo : YesNo
>Choice : any
>Yes : Choice.Yes
>Choice : any
>No : Choice.No
type NoYes = Choice.No | Choice.Yes;
>NoYes : YesNo
>Choice : any
>No : Choice.No
>Choice : any
>Yes : Choice.Yes
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
>UnknownYesNo : Choice
>Choice : any
>Unknown : Choice.Unknown
>Choice : any
>Yes : Choice.Yes
>Choice : any
>No : Choice.No
function f1() {
>f1 : () => void
var a: YesNo;
>a : YesNo
>YesNo : YesNo
var a: NoYes;
>a : YesNo
>NoYes : YesNo
var a: Choice.Yes | Choice.No;
>a : YesNo
>Choice : any
>Yes : Choice.Yes
>Choice : any
>No : Choice.No
var a: Choice.No | Choice.Yes;
>a : YesNo
>Choice : any
>No : Choice.No
>Choice : any
>Yes : Choice.Yes
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
>f2 : (a: YesNo, b: Choice, c: Choice) => void
>a : YesNo
>YesNo : YesNo
>b : Choice
>UnknownYesNo : Choice
>c : Choice
>Choice : Choice
b = a;
>b = a : YesNo
>b : Choice
>a : YesNo
c = a;
>c = a : YesNo
>c : Choice
>a : YesNo
c = b;
>c = b : YesNo
>c : Choice
>b : YesNo
}
function f3(a: Choice.Yes, b: YesNo) {
>f3 : (a: Choice.Yes, b: YesNo) => void
>a : Choice.Yes
>Choice : any
>Yes : Choice.Yes
>b : YesNo
>YesNo : YesNo
var x = a + b;
>x : string
>a + b : string
>a : Choice.Yes
>b : YesNo
var y = a == b;
>y : boolean
>a == b : boolean
>a : Choice.Yes
>b : YesNo
var y = a != b;
>y : boolean
>a != b : boolean
>a : Choice.Yes
>b : YesNo
var y = a === b;
>y : boolean
>a === b : boolean
>a : Choice.Yes
>b : YesNo
var y = a !== b;
>y : boolean
>a !== b : boolean
>a : Choice.Yes
>b : YesNo
var y = a > b;
>y : boolean
>a > b : boolean
>a : Choice.Yes
>b : YesNo
var y = a < b;
>y : boolean
>a < b : boolean
>a : Choice.Yes
>b : YesNo
var y = a >= b;
>y : boolean
>a >= b : boolean
>a : Choice.Yes
>b : YesNo
var y = a <= b;
>y : boolean
>a <= b : boolean
>a : Choice.Yes
>b : YesNo
var y = !b;
>y : boolean
>!b : boolean
>b : YesNo
}
declare function g(x: Choice.Yes): string;
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>x : Choice.Yes
>Choice : any
>Yes : Choice.Yes
declare function g(x: Choice.No): boolean;
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>x : Choice.No
>Choice : any
>No : Choice.No
declare function g(x: Choice): number;
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>x : Choice
>Choice : Choice
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
>f5 : (a: YesNo, b: Choice, c: Choice) => void
>a : YesNo
>YesNo : YesNo
>b : Choice
>UnknownYesNo : Choice
>c : Choice
>Choice : Choice
var z1 = g(Choice.Yes);
>z1 : string
>g(Choice.Yes) : string
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
var z2 = g(Choice.No);
>z2 : boolean
>g(Choice.No) : boolean
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
var z3 = g(a);
>z3 : number
>g(a) : number
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>a : YesNo
var z4 = g(b);
>z4 : number
>g(b) : number
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>b : Choice
var z5 = g(c);
>z5 : number
>g(c) : number
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>c : Choice
}
function assertNever(x: never): never {
>assertNever : (x: never) => never
>x : never
throw new Error("Unexpected value");
>new Error("Unexpected value") : Error
>Error : ErrorConstructor
>"Unexpected value" : "Unexpected value"
}
function f10(x: YesNo) {
>f10 : (x: YesNo) => "true" | "false"
>x : YesNo
>YesNo : YesNo
switch (x) {
>x : YesNo
case Choice.Yes: return "true";
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>"true" : "true"
case Choice.No: return "false";
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>"false" : "false"
}
}
function f11(x: YesNo) {
>f11 : (x: YesNo) => "true" | "false"
>x : YesNo
>YesNo : YesNo
switch (x) {
>x : YesNo
case Choice.Yes: return "true";
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>"true" : "true"
case Choice.No: return "false";
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>"false" : "false"
}
return assertNever(x);
>assertNever(x) : never
>assertNever : (x: never) => never
>x : never
}
function f12(x: UnknownYesNo) {
>f12 : (x: Choice) => void
>x : Choice
>UnknownYesNo : Choice
if (x) {
>x : Choice
x;
>x : YesNo
}
else {
x;
>x : Choice
}
}
function f13(x: UnknownYesNo) {
>f13 : (x: Choice) => void
>x : Choice
>UnknownYesNo : Choice
if (x === Choice.Yes) {
>x === Choice.Yes : boolean
>x : Choice
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
x;
>x : Choice.Yes
}
else {
x;
>x : Choice.Unknown | Choice.No
}
}
type Item =
>Item : Item
{ kind: Choice.Yes, a: string } |
>kind : Choice.Yes
>Choice : any
>Yes : Choice.Yes
>a : string
{ kind: Choice.No, b: string };
>kind : Choice.No
>Choice : any
>No : Choice.No
>b : string
function f20(x: Item) {
>f20 : (x: Item) => string
>x : Item
>Item : Item
switch (x.kind) {
>x.kind : YesNo
>x : Item
>kind : YesNo
case Choice.Yes: return x.a;
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>x.a : string
>x : { kind: Choice.Yes; a: string; }
>a : string
case Choice.No: return x.b;
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>x.b : string
>x : { kind: Choice.No; b: string; }
>b : string
}
}
function f21(x: Item) {
>f21 : (x: Item) => string
>x : Item
>Item : Item
switch (x.kind) {
>x.kind : YesNo
>x : Item
>kind : YesNo
case Choice.Yes: return x.a;
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>x.a : string
>x : { kind: Choice.Yes; a: string; }
>a : string
case Choice.No: return x.b;
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>x.b : string
>x : { kind: Choice.No; b: string; }
>b : string
}
return assertNever(x);
>assertNever(x) : never
>assertNever : (x: never) => never
>x : never
}
@@ -0,0 +1,178 @@
//// [stringEnumLiteralTypes2.ts]
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
type YesNo = Choice.Yes | Choice.No;
type NoYes = Choice.No | Choice.Yes;
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
function f1() {
var a: YesNo;
var a: NoYes;
var a: Choice.Yes | Choice.No;
var a: Choice.No | Choice.Yes;
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
b = a;
c = a;
c = b;
}
function f3(a: Choice.Yes, b: YesNo) {
var x = a + b;
var y = a == b;
var y = a != b;
var y = a === b;
var y = a !== b;
var y = a > b;
var y = a < b;
var y = a >= b;
var y = a <= b;
var y = !b;
}
declare function g(x: Choice.Yes): string;
declare function g(x: Choice.No): boolean;
declare function g(x: Choice): number;
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
var z1 = g(Choice.Yes);
var z2 = g(Choice.No);
var z3 = g(a);
var z4 = g(b);
var z5 = g(c);
}
function assertNever(x: never): never {
throw new Error("Unexpected value");
}
function f10(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
}
function f11(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
return assertNever(x);
}
function f12(x: UnknownYesNo) {
if (x) {
x;
}
else {
x;
}
}
function f13(x: UnknownYesNo) {
if (x === Choice.Yes) {
x;
}
else {
x;
}
}
type Item =
{ kind: Choice.Yes, a: string } |
{ kind: Choice.No, b: string };
function f20(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
}
function f21(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
return assertNever(x);
}
//// [stringEnumLiteralTypes2.js]
;
function f1() {
var a;
var a;
var a;
var a;
}
function f2(a, b, c) {
b = a;
c = a;
c = b;
}
function f3(a, b) {
var x = a + b;
var y = a == b;
var y = a != b;
var y = a === b;
var y = a !== b;
var y = a > b;
var y = a < b;
var y = a >= b;
var y = a <= b;
var y = !b;
}
function f5(a, b, c) {
var z1 = g("yes" /* Yes */);
var z2 = g("no" /* No */);
var z3 = g(a);
var z4 = g(b);
var z5 = g(c);
}
function assertNever(x) {
throw new Error("Unexpected value");
}
function f10(x) {
switch (x) {
case "yes" /* Yes */: return "true";
case "no" /* No */: return "false";
}
}
function f11(x) {
switch (x) {
case "yes" /* Yes */: return "true";
case "no" /* No */: return "false";
}
return assertNever(x);
}
function f12(x) {
if (x) {
x;
}
else {
x;
}
}
function f13(x) {
if (x === "yes" /* Yes */) {
x;
}
else {
x;
}
}
function f20(x) {
switch (x.kind) {
case "yes" /* Yes */: return x.a;
case "no" /* No */: return x.b;
}
}
function f21(x) {
switch (x.kind) {
case "yes" /* Yes */: return x.a;
case "no" /* No */: return x.b;
}
return assertNever(x);
}
@@ -0,0 +1,353 @@
=== tests/cases/conformance/types/literal/stringEnumLiteralTypes2.ts ===
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Unknown : Symbol(Choice.Unknown, Decl(stringEnumLiteralTypes2.ts, 0, 19))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
type YesNo = Choice.Yes | Choice.No;
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes2.ts, 0, 59))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
type NoYes = Choice.No | Choice.Yes;
>NoYes : Symbol(NoYes, Decl(stringEnumLiteralTypes2.ts, 2, 36))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes2.ts, 3, 36))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Unknown : Symbol(Choice.Unknown, Decl(stringEnumLiteralTypes2.ts, 0, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
function f1() {
>f1 : Symbol(f1, Decl(stringEnumLiteralTypes2.ts, 4, 60))
var a: YesNo;
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 7, 7), Decl(stringEnumLiteralTypes2.ts, 8, 7), Decl(stringEnumLiteralTypes2.ts, 9, 7), Decl(stringEnumLiteralTypes2.ts, 10, 7))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes2.ts, 0, 59))
var a: NoYes;
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 7, 7), Decl(stringEnumLiteralTypes2.ts, 8, 7), Decl(stringEnumLiteralTypes2.ts, 9, 7), Decl(stringEnumLiteralTypes2.ts, 10, 7))
>NoYes : Symbol(NoYes, Decl(stringEnumLiteralTypes2.ts, 2, 36))
var a: Choice.Yes | Choice.No;
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 7, 7), Decl(stringEnumLiteralTypes2.ts, 8, 7), Decl(stringEnumLiteralTypes2.ts, 9, 7), Decl(stringEnumLiteralTypes2.ts, 10, 7))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
var a: Choice.No | Choice.Yes;
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 7, 7), Decl(stringEnumLiteralTypes2.ts, 8, 7), Decl(stringEnumLiteralTypes2.ts, 9, 7), Decl(stringEnumLiteralTypes2.ts, 10, 7))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
>f2 : Symbol(f2, Decl(stringEnumLiteralTypes2.ts, 11, 1))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 13, 12))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes2.ts, 0, 59))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 13, 21))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes2.ts, 3, 36))
>c : Symbol(c, Decl(stringEnumLiteralTypes2.ts, 13, 38))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
b = a;
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 13, 21))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 13, 12))
c = a;
>c : Symbol(c, Decl(stringEnumLiteralTypes2.ts, 13, 38))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 13, 12))
c = b;
>c : Symbol(c, Decl(stringEnumLiteralTypes2.ts, 13, 38))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 13, 21))
}
function f3(a: Choice.Yes, b: YesNo) {
>f3 : Symbol(f3, Decl(stringEnumLiteralTypes2.ts, 17, 1))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes2.ts, 0, 59))
var x = a + b;
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 20, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a == b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a != b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a === b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a !== b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a > b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a < b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a >= b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = a <= b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 19, 12))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
var y = !b;
>y : Symbol(y, Decl(stringEnumLiteralTypes2.ts, 21, 7), Decl(stringEnumLiteralTypes2.ts, 22, 7), Decl(stringEnumLiteralTypes2.ts, 23, 7), Decl(stringEnumLiteralTypes2.ts, 24, 7), Decl(stringEnumLiteralTypes2.ts, 25, 7), Decl(stringEnumLiteralTypes2.ts, 26, 7), Decl(stringEnumLiteralTypes2.ts, 27, 7), Decl(stringEnumLiteralTypes2.ts, 28, 7), Decl(stringEnumLiteralTypes2.ts, 29, 7))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 19, 26))
}
declare function g(x: Choice.Yes): string;
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 32, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
declare function g(x: Choice.No): boolean;
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 33, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
declare function g(x: Choice): number;
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 34, 19))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
>f5 : Symbol(f5, Decl(stringEnumLiteralTypes2.ts, 34, 38))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 36, 12))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes2.ts, 0, 59))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 36, 21))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes2.ts, 3, 36))
>c : Symbol(c, Decl(stringEnumLiteralTypes2.ts, 36, 38))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
var z1 = g(Choice.Yes);
>z1 : Symbol(z1, Decl(stringEnumLiteralTypes2.ts, 37, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
var z2 = g(Choice.No);
>z2 : Symbol(z2, Decl(stringEnumLiteralTypes2.ts, 38, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
var z3 = g(a);
>z3 : Symbol(z3, Decl(stringEnumLiteralTypes2.ts, 39, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 36, 12))
var z4 = g(b);
>z4 : Symbol(z4, Decl(stringEnumLiteralTypes2.ts, 40, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 36, 21))
var z5 = g(c);
>z5 : Symbol(z5, Decl(stringEnumLiteralTypes2.ts, 41, 7))
>g : Symbol(g, Decl(stringEnumLiteralTypes2.ts, 30, 1), Decl(stringEnumLiteralTypes2.ts, 32, 42), Decl(stringEnumLiteralTypes2.ts, 33, 42))
>c : Symbol(c, Decl(stringEnumLiteralTypes2.ts, 36, 38))
}
function assertNever(x: never): never {
>assertNever : Symbol(assertNever, Decl(stringEnumLiteralTypes2.ts, 42, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 44, 21))
throw new Error("Unexpected value");
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
}
function f10(x: YesNo) {
>f10 : Symbol(f10, Decl(stringEnumLiteralTypes2.ts, 46, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 48, 13))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes2.ts, 0, 59))
switch (x) {
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 48, 13))
case Choice.Yes: return "true";
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
case Choice.No: return "false";
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
}
}
function f11(x: YesNo) {
>f11 : Symbol(f11, Decl(stringEnumLiteralTypes2.ts, 53, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 55, 13))
>YesNo : Symbol(YesNo, Decl(stringEnumLiteralTypes2.ts, 0, 59))
switch (x) {
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 55, 13))
case Choice.Yes: return "true";
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
case Choice.No: return "false";
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
}
return assertNever(x);
>assertNever : Symbol(assertNever, Decl(stringEnumLiteralTypes2.ts, 42, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 55, 13))
}
function f12(x: UnknownYesNo) {
>f12 : Symbol(f12, Decl(stringEnumLiteralTypes2.ts, 61, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 63, 13))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes2.ts, 3, 36))
if (x) {
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 63, 13))
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 63, 13))
}
else {
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 63, 13))
}
}
function f13(x: UnknownYesNo) {
>f13 : Symbol(f13, Decl(stringEnumLiteralTypes2.ts, 70, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 72, 13))
>UnknownYesNo : Symbol(UnknownYesNo, Decl(stringEnumLiteralTypes2.ts, 3, 36))
if (x === Choice.Yes) {
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 72, 13))
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 72, 13))
}
else {
x;
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 72, 13))
}
}
type Item =
>Item : Symbol(Item, Decl(stringEnumLiteralTypes2.ts, 79, 1))
{ kind: Choice.Yes, a: string } |
>kind : Symbol(kind, Decl(stringEnumLiteralTypes2.ts, 82, 5))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 82, 23))
{ kind: Choice.No, b: string };
>kind : Symbol(kind, Decl(stringEnumLiteralTypes2.ts, 83, 5))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 83, 22))
function f20(x: Item) {
>f20 : Symbol(f20, Decl(stringEnumLiteralTypes2.ts, 83, 35))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 85, 13))
>Item : Symbol(Item, Decl(stringEnumLiteralTypes2.ts, 79, 1))
switch (x.kind) {
>x.kind : Symbol(kind, Decl(stringEnumLiteralTypes2.ts, 82, 5), Decl(stringEnumLiteralTypes2.ts, 83, 5))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 85, 13))
>kind : Symbol(kind, Decl(stringEnumLiteralTypes2.ts, 82, 5), Decl(stringEnumLiteralTypes2.ts, 83, 5))
case Choice.Yes: return x.a;
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>x.a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 82, 23))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 85, 13))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 82, 23))
case Choice.No: return x.b;
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>x.b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 83, 22))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 85, 13))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 83, 22))
}
}
function f21(x: Item) {
>f21 : Symbol(f21, Decl(stringEnumLiteralTypes2.ts, 90, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 92, 13))
>Item : Symbol(Item, Decl(stringEnumLiteralTypes2.ts, 79, 1))
switch (x.kind) {
>x.kind : Symbol(kind, Decl(stringEnumLiteralTypes2.ts, 82, 5), Decl(stringEnumLiteralTypes2.ts, 83, 5))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 92, 13))
>kind : Symbol(kind, Decl(stringEnumLiteralTypes2.ts, 82, 5), Decl(stringEnumLiteralTypes2.ts, 83, 5))
case Choice.Yes: return x.a;
>Choice.Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>Yes : Symbol(Choice.Yes, Decl(stringEnumLiteralTypes2.ts, 0, 33))
>x.a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 82, 23))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 92, 13))
>a : Symbol(a, Decl(stringEnumLiteralTypes2.ts, 82, 23))
case Choice.No: return x.b;
>Choice.No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>Choice : Symbol(Choice, Decl(stringEnumLiteralTypes2.ts, 0, 0))
>No : Symbol(Choice.No, Decl(stringEnumLiteralTypes2.ts, 0, 46))
>x.b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 83, 22))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 92, 13))
>b : Symbol(b, Decl(stringEnumLiteralTypes2.ts, 83, 22))
}
return assertNever(x);
>assertNever : Symbol(assertNever, Decl(stringEnumLiteralTypes2.ts, 42, 1))
>x : Symbol(x, Decl(stringEnumLiteralTypes2.ts, 92, 13))
}
@@ -0,0 +1,383 @@
=== tests/cases/conformance/types/literal/stringEnumLiteralTypes2.ts ===
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
>Choice : Choice
>Unknown : Choice.Unknown
>"" : ""
>Yes : Choice.Yes
>"yes" : "yes"
>No : Choice.No
>"no" : "no"
type YesNo = Choice.Yes | Choice.No;
>YesNo : YesNo
>Choice : any
>Yes : Choice.Yes
>Choice : any
>No : Choice.No
type NoYes = Choice.No | Choice.Yes;
>NoYes : YesNo
>Choice : any
>No : Choice.No
>Choice : any
>Yes : Choice.Yes
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
>UnknownYesNo : Choice
>Choice : any
>Unknown : Choice.Unknown
>Choice : any
>Yes : Choice.Yes
>Choice : any
>No : Choice.No
function f1() {
>f1 : () => void
var a: YesNo;
>a : YesNo
>YesNo : YesNo
var a: NoYes;
>a : YesNo
>NoYes : YesNo
var a: Choice.Yes | Choice.No;
>a : YesNo
>Choice : any
>Yes : Choice.Yes
>Choice : any
>No : Choice.No
var a: Choice.No | Choice.Yes;
>a : YesNo
>Choice : any
>No : Choice.No
>Choice : any
>Yes : Choice.Yes
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
>f2 : (a: YesNo, b: Choice, c: Choice) => void
>a : YesNo
>YesNo : YesNo
>b : Choice
>UnknownYesNo : Choice
>c : Choice
>Choice : Choice
b = a;
>b = a : YesNo
>b : Choice
>a : YesNo
c = a;
>c = a : YesNo
>c : Choice
>a : YesNo
c = b;
>c = b : YesNo
>c : Choice
>b : YesNo
}
function f3(a: Choice.Yes, b: YesNo) {
>f3 : (a: Choice.Yes, b: YesNo) => void
>a : Choice.Yes
>Choice : any
>Yes : Choice.Yes
>b : YesNo
>YesNo : YesNo
var x = a + b;
>x : string
>a + b : string
>a : Choice.Yes
>b : YesNo
var y = a == b;
>y : boolean
>a == b : boolean
>a : Choice.Yes
>b : YesNo
var y = a != b;
>y : boolean
>a != b : boolean
>a : Choice.Yes
>b : YesNo
var y = a === b;
>y : boolean
>a === b : boolean
>a : Choice.Yes
>b : YesNo
var y = a !== b;
>y : boolean
>a !== b : boolean
>a : Choice.Yes
>b : YesNo
var y = a > b;
>y : boolean
>a > b : boolean
>a : Choice.Yes
>b : YesNo
var y = a < b;
>y : boolean
>a < b : boolean
>a : Choice.Yes
>b : YesNo
var y = a >= b;
>y : boolean
>a >= b : boolean
>a : Choice.Yes
>b : YesNo
var y = a <= b;
>y : boolean
>a <= b : boolean
>a : Choice.Yes
>b : YesNo
var y = !b;
>y : boolean
>!b : false
>b : YesNo
}
declare function g(x: Choice.Yes): string;
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>x : Choice.Yes
>Choice : any
>Yes : Choice.Yes
declare function g(x: Choice.No): boolean;
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>x : Choice.No
>Choice : any
>No : Choice.No
declare function g(x: Choice): number;
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>x : Choice
>Choice : Choice
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
>f5 : (a: YesNo, b: Choice, c: Choice) => void
>a : YesNo
>YesNo : YesNo
>b : Choice
>UnknownYesNo : Choice
>c : Choice
>Choice : Choice
var z1 = g(Choice.Yes);
>z1 : string
>g(Choice.Yes) : string
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
var z2 = g(Choice.No);
>z2 : boolean
>g(Choice.No) : boolean
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
var z3 = g(a);
>z3 : number
>g(a) : number
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>a : YesNo
var z4 = g(b);
>z4 : number
>g(b) : number
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>b : Choice
var z5 = g(c);
>z5 : number
>g(c) : number
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
>c : Choice
}
function assertNever(x: never): never {
>assertNever : (x: never) => never
>x : never
throw new Error("Unexpected value");
>new Error("Unexpected value") : Error
>Error : ErrorConstructor
>"Unexpected value" : "Unexpected value"
}
function f10(x: YesNo) {
>f10 : (x: YesNo) => "true" | "false"
>x : YesNo
>YesNo : YesNo
switch (x) {
>x : YesNo
case Choice.Yes: return "true";
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>"true" : "true"
case Choice.No: return "false";
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>"false" : "false"
}
}
function f11(x: YesNo) {
>f11 : (x: YesNo) => "true" | "false"
>x : YesNo
>YesNo : YesNo
switch (x) {
>x : YesNo
case Choice.Yes: return "true";
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>"true" : "true"
case Choice.No: return "false";
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>"false" : "false"
}
return assertNever(x);
>assertNever(x) : never
>assertNever : (x: never) => never
>x : never
}
function f12(x: UnknownYesNo) {
>f12 : (x: Choice) => void
>x : Choice
>UnknownYesNo : Choice
if (x) {
>x : Choice
x;
>x : YesNo
}
else {
x;
>x : Choice.Unknown
}
}
function f13(x: UnknownYesNo) {
>f13 : (x: Choice) => void
>x : Choice
>UnknownYesNo : Choice
if (x === Choice.Yes) {
>x === Choice.Yes : boolean
>x : Choice
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
x;
>x : Choice.Yes
}
else {
x;
>x : Choice.Unknown | Choice.No
}
}
type Item =
>Item : Item
{ kind: Choice.Yes, a: string } |
>kind : Choice.Yes
>Choice : any
>Yes : Choice.Yes
>a : string
{ kind: Choice.No, b: string };
>kind : Choice.No
>Choice : any
>No : Choice.No
>b : string
function f20(x: Item) {
>f20 : (x: Item) => string
>x : Item
>Item : Item
switch (x.kind) {
>x.kind : YesNo
>x : Item
>kind : YesNo
case Choice.Yes: return x.a;
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>x.a : string
>x : { kind: Choice.Yes; a: string; }
>a : string
case Choice.No: return x.b;
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>x.b : string
>x : { kind: Choice.No; b: string; }
>b : string
}
}
function f21(x: Item) {
>f21 : (x: Item) => string
>x : Item
>Item : Item
switch (x.kind) {
>x.kind : YesNo
>x : Item
>kind : YesNo
case Choice.Yes: return x.a;
>Choice.Yes : Choice.Yes
>Choice : typeof Choice
>Yes : Choice.Yes
>x.a : string
>x : { kind: Choice.Yes; a: string; }
>a : string
case Choice.No: return x.b;
>Choice.No : Choice.No
>Choice : typeof Choice
>No : Choice.No
>x.b : string
>x : { kind: Choice.No; b: string; }
>b : string
}
return assertNever(x);
>assertNever(x) : never
>assertNever : (x: never) => never
>x : never
}
@@ -0,0 +1,166 @@
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(10,5): error TS2322: Type 'YesNo' is not assignable to type 'Choice.Yes'.
Type 'Choice.No' is not assignable to type 'Choice.Yes'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(11,5): error TS2322: Type 'Choice' is not assignable to type 'Choice.Yes'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(12,5): error TS2322: Type 'Choice' is not assignable to type 'Choice.Yes'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(18,5): error TS2322: Type 'Choice' is not assignable to type 'YesNo'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(19,5): error TS2322: Type 'Choice' is not assignable to type 'YesNo'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(37,5): error TS2322: Type 'Choice.Unknown' is not assignable to type 'Choice.Yes'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(39,5): error TS2322: Type 'Choice.No' is not assignable to type 'Choice.Yes'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(40,5): error TS2322: Type 'Choice.Unknown' is not assignable to type 'YesNo'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(52,5): error TS2365: Operator '===' cannot be applied to types 'Choice.Yes' and 'Choice.Unknown'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(54,5): error TS2365: Operator '===' cannot be applied to types 'Choice.Yes' and 'Choice.No'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(55,5): error TS2365: Operator '===' cannot be applied to types 'YesNo' and 'Choice.Unknown'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(87,14): error TS2678: Type 'Choice.Unknown' is not comparable to type 'Choice.Yes'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(89,14): error TS2678: Type 'Choice.No' is not comparable to type 'Choice.Yes'.
tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts(96,14): error TS2678: Type 'Choice.Unknown' is not comparable to type 'YesNo'.
==== tests/cases/conformance/types/literal/stringEnumLiteralTypes3.ts (14 errors) ====
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
type Yes = Choice.Yes;
type YesNo = Choice.Yes | Choice.No;
type NoYes = Choice.No | Choice.Yes;
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
function f1(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a = a;
a = b;
~
!!! error TS2322: Type 'YesNo' is not assignable to type 'Choice.Yes'.
!!! error TS2322: Type 'Choice.No' is not assignable to type 'Choice.Yes'.
a = c;
~
!!! error TS2322: Type 'Choice' is not assignable to type 'Choice.Yes'.
a = d;
~
!!! error TS2322: Type 'Choice' is not assignable to type 'Choice.Yes'.
}
function f2(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
b = a;
b = b;
b = c;
~
!!! error TS2322: Type 'Choice' is not assignable to type 'YesNo'.
b = d;
~
!!! error TS2322: Type 'Choice' is not assignable to type 'YesNo'.
}
function f3(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
c = a;
c = b;
c = c;
c = d;
}
function f4(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
d = a;
d = b;
d = c;
d = d;
}
function f5(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a = Choice.Unknown;
~
!!! error TS2322: Type 'Choice.Unknown' is not assignable to type 'Choice.Yes'.
a = Choice.Yes;
a = Choice.No;
~
!!! error TS2322: Type 'Choice.No' is not assignable to type 'Choice.Yes'.
b = Choice.Unknown;
~
!!! error TS2322: Type 'Choice.Unknown' is not assignable to type 'YesNo'.
b = Choice.Yes;
b = Choice.No;
c = Choice.Unknown;
c = Choice.Yes;
c = Choice.No;
d = Choice.Unknown;
d = Choice.Yes;
d = Choice.No;
}
function f6(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a === Choice.Unknown;
~~~~~~~~~~~~~~~~~~~~
!!! error TS2365: Operator '===' cannot be applied to types 'Choice.Yes' and 'Choice.Unknown'.
a === Choice.Yes;
a === Choice.No;
~~~~~~~~~~~~~~~
!!! error TS2365: Operator '===' cannot be applied to types 'Choice.Yes' and 'Choice.No'.
b === Choice.Unknown;
~~~~~~~~~~~~~~~~~~~~
!!! error TS2365: Operator '===' cannot be applied to types 'YesNo' and 'Choice.Unknown'.
b === Choice.Yes;
b === Choice.No;
c === Choice.Unknown;
c === Choice.Yes;
c === Choice.No;
d === Choice.Unknown;
d === Choice.Yes;
d === Choice.No;
}
function f7(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a === a;
a === b;
a === c;
a === d;
b === a;
b === b;
b === c;
b === d;
c === a;
c === b;
c === c;
c === d;
d === a;
d === b;
d === c;
d === d;
}
function f10(x: Yes): Yes {
switch (x) {
case Choice.Unknown: return x;
~~~~~~~~~~~~~~
!!! error TS2678: Type 'Choice.Unknown' is not comparable to type 'Choice.Yes'.
case Choice.Yes: return x;
case Choice.No: return x;
~~~~~~~~~
!!! error TS2678: Type 'Choice.No' is not comparable to type 'Choice.Yes'.
}
return x;
}
function f11(x: YesNo): YesNo {
switch (x) {
case Choice.Unknown: return x;
~~~~~~~~~~~~~~
!!! error TS2678: Type 'Choice.Unknown' is not comparable to type 'YesNo'.
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f12(x: UnknownYesNo): UnknownYesNo {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f13(x: Choice): Choice {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
@@ -0,0 +1,225 @@
//// [stringEnumLiteralTypes3.ts]
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
type Yes = Choice.Yes;
type YesNo = Choice.Yes | Choice.No;
type NoYes = Choice.No | Choice.Yes;
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
function f1(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a = a;
a = b;
a = c;
a = d;
}
function f2(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
b = a;
b = b;
b = c;
b = d;
}
function f3(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
c = a;
c = b;
c = c;
c = d;
}
function f4(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
d = a;
d = b;
d = c;
d = d;
}
function f5(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a = Choice.Unknown;
a = Choice.Yes;
a = Choice.No;
b = Choice.Unknown;
b = Choice.Yes;
b = Choice.No;
c = Choice.Unknown;
c = Choice.Yes;
c = Choice.No;
d = Choice.Unknown;
d = Choice.Yes;
d = Choice.No;
}
function f6(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a === Choice.Unknown;
a === Choice.Yes;
a === Choice.No;
b === Choice.Unknown;
b === Choice.Yes;
b === Choice.No;
c === Choice.Unknown;
c === Choice.Yes;
c === Choice.No;
d === Choice.Unknown;
d === Choice.Yes;
d === Choice.No;
}
function f7(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a === a;
a === b;
a === c;
a === d;
b === a;
b === b;
b === c;
b === d;
c === a;
c === b;
c === c;
c === d;
d === a;
d === b;
d === c;
d === d;
}
function f10(x: Yes): Yes {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f11(x: YesNo): YesNo {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f12(x: UnknownYesNo): UnknownYesNo {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f13(x: Choice): Choice {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
//// [stringEnumLiteralTypes3.js]
;
function f1(a, b, c, d) {
a = a;
a = b;
a = c;
a = d;
}
function f2(a, b, c, d) {
b = a;
b = b;
b = c;
b = d;
}
function f3(a, b, c, d) {
c = a;
c = b;
c = c;
c = d;
}
function f4(a, b, c, d) {
d = a;
d = b;
d = c;
d = d;
}
function f5(a, b, c, d) {
a = "" /* Unknown */;
a = "yes" /* Yes */;
a = "no" /* No */;
b = "" /* Unknown */;
b = "yes" /* Yes */;
b = "no" /* No */;
c = "" /* Unknown */;
c = "yes" /* Yes */;
c = "no" /* No */;
d = "" /* Unknown */;
d = "yes" /* Yes */;
d = "no" /* No */;
}
function f6(a, b, c, d) {
a === "" /* Unknown */;
a === "yes" /* Yes */;
a === "no" /* No */;
b === "" /* Unknown */;
b === "yes" /* Yes */;
b === "no" /* No */;
c === "" /* Unknown */;
c === "yes" /* Yes */;
c === "no" /* No */;
d === "" /* Unknown */;
d === "yes" /* Yes */;
d === "no" /* No */;
}
function f7(a, b, c, d) {
a === a;
a === b;
a === c;
a === d;
b === a;
b === b;
b === c;
b === d;
c === a;
c === b;
c === c;
c === d;
d === a;
d === b;
d === c;
d === d;
}
function f10(x) {
switch (x) {
case "" /* Unknown */: return x;
case "yes" /* Yes */: return x;
case "no" /* No */: return x;
}
return x;
}
function f11(x) {
switch (x) {
case "" /* Unknown */: return x;
case "yes" /* Yes */: return x;
case "no" /* No */: return x;
}
return x;
}
function f12(x) {
switch (x) {
case "" /* Unknown */: return x;
case "yes" /* Yes */: return x;
case "no" /* No */: return x;
}
return x;
}
function f13(x) {
switch (x) {
case "" /* Unknown */: return x;
case "yes" /* Yes */: return x;
case "no" /* No */: return x;
}
return x;
}
@@ -12,21 +12,21 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(28,5): error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'string | number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(29,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'string | number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(30,5): error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'string | number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(35,5): error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(37,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(39,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(40,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(41,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(42,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(43,5): error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(44,5): error TS2411: Property 'foo11' of type 'A2<number>' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(45,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(46,5): error TS2411: Property 'foo13' of type '<T>(x: T) => T' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(47,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(48,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(49,5): error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(50,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(51,5): error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number | E'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(35,5): error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(37,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(39,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(40,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(41,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(42,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(43,5): error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(44,5): error TS2411: Property 'foo11' of type 'A2<number>' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(45,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(46,5): error TS2411: Property 'foo13' of type '<T>(x: T) => T' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(47,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(48,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(49,5): error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(50,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(51,5): error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number'.
==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts (29 errors) ====
@@ -94,49 +94,49 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf
foo: any; // ok
foo2: string; // error
~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number'.
foo3: number; // ok
foo4: boolean; // error
~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number'.
foo5: E; // ok
foo6: Date; // error
~~~~~~~~~~~
!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number'.
foo7: RegExp; // error
~~~~~~~~~~~~~
!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number'.
foo8: { bar: number }; // error
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number'.
foo9: I8; // error
~~~~~~~~~
!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number'.
foo10: A; // error
~~~~~~~~~
!!! error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number'.
foo11: A2<number>; // error
~~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo11' of type 'A2<number>' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo11' of type 'A2<number>' is not assignable to string index type 'number'.
foo12: (x) => number; //error
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number'.
foo13: <T>(x: T) => T; // error
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo13' of type '<T>(x: T) => T' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo13' of type '<T>(x: T) => T' is not assignable to string index type 'number'.
foo14: typeof f; // error
~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number'.
foo15: typeof c; // error
~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number'.
foo16: T; // error
~~~~~~~~~
!!! error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number'.
foo17: Object; // error
~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number'.
foo18: {}; // error
~~~~~~~~~~
!!! error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number | E'.
!!! error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number'.
}
@@ -1,10 +1,8 @@
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjectLiteral.ts(30,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
Type argument candidate 'E1' is not a valid type argument because it is not a supertype of candidate '0'.
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjectLiteral.ts(35,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
Type argument candidate 'E1' is not a valid type argument because it is not a supertype of candidate 'E2'.
==== tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjectLiteral.ts (2 errors) ====
==== tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjectLiteral.ts (1 errors) ====
interface Computed<T> {
read(): T;
write(value: T);
@@ -35,9 +33,6 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjec
var v1 = f1({ w: x => x, r: () => 0 }, 0);
var v1 = f1({ w: x => x, r: () => 0 }, E1.X);
var v1 = f1({ w: x => x, r: () => E1.X }, 0);
~~
!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
!!! error TS2453: Type argument candidate 'E1' is not a valid type argument because it is not a supertype of candidate '0'.
var v2: E1;
var v2 = f1({ w: x => x, r: () => E1.X }, E1.X);
@@ -1,37 +1,36 @@
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(15,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(21,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'string'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(22,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'string'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(22,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'string'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(28,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'boolean'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(29,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'boolean'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(29,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'boolean'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(35,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'Date'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(36,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'Date'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(36,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'Date'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(42,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'RegExp'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(43,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'RegExp'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(43,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'RegExp'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(49,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '{ bar: number; }'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(50,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '{ bar: number; }'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(50,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '{ bar: number; }'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(56,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number[]'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(57,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'number[]'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(57,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'number[]'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(63,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'I8'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(64,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'I8'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(64,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'I8'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(70,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(71,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(71,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(77,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A2<number>'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(78,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A2<number>'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(78,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A2<number>'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(84,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: any) => number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(85,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '(x: any) => number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(85,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '(x: any) => number'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(91,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '<T>(x: T) => T'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(92,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '<T>(x: T) => T'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(92,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '<T>(x: T) => T'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(99,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'E2'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(100,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'E2'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(110,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof f'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(111,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof f'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(111,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof f'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(121,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof c'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(122,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof c'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(122,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof c'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(128,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'T'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(129,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'T'.
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(129,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'T'.
==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts (31 errors) ====
==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts (30 errors) ====
enum e {
e1,
e2
@@ -59,7 +58,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'string'.
foo2: e | number; // error e and number both not subtype of string
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'string'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'string'.
}
// error cases
@@ -70,7 +69,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'boolean'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'boolean'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'boolean'.
}
@@ -81,7 +80,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'Date'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'Date'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'Date'.
}
@@ -92,7 +91,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'RegExp'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'RegExp'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'RegExp'.
}
@@ -103,7 +102,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '{ bar: number; }'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '{ bar: number; }'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '{ bar: number; }'.
}
@@ -114,7 +113,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number[]'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'number[]'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'number[]'.
}
@@ -125,7 +124,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'I8'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'I8'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'I8'.
}
class A { foo: number; }
@@ -136,7 +135,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A'.
}
class A2<T> { foo: T; }
@@ -147,7 +146,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A2<number>'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A2<number>'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A2<number>'.
}
@@ -158,7 +157,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: any) => number'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '(x: any) => number'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '(x: any) => number'.
}
@@ -169,7 +168,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '<T>(x: T) => T'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '<T>(x: T) => T'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '<T>(x: T) => T'.
}
@@ -180,8 +179,6 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'E2'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'E2'.
}
@@ -196,7 +193,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof f'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof f'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof f'.
}
@@ -211,7 +208,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof c'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof c'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof c'.
}
@@ -222,7 +219,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty
!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'T'.
foo2: e | number;
~~~~~~~~~~~~~~~~~
!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'T'.
!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'T'.
}
interface I19 {
+3 -3
View File
@@ -11,9 +11,9 @@ var x: number = E1.A;
// Enum object type is anonymous with properties of the enum type and numeric indexer
var e = E1;
var e: {
readonly A: E1;
readonly B: E1;
readonly C: E1;
readonly A: E1.A;
readonly B: E1.B;
readonly C: E1.C;
readonly [n: number]: string;
};
var e: typeof E1;
@@ -0,0 +1,80 @@
// @declaration: true
// An enum type where each member has no initializer or an initializer that specififes
// a numeric literal, a string literal, or a single identifier naming another member in
// the enum type is classified as a literal enum type. An enum type that doesn't adhere
// to this pattern is classified as a numeric enum type.
// Examples of literal enum types
enum E01 {
A
}
enum E02 {
A = 123
}
enum E03 {
A = "hello"
}
enum E04 {
A,
B,
C
}
enum E05 {
A,
B = 10,
C
}
enum E06 {
A = "one",
B = "two",
C = "three"
}
enum E07 {
A,
B,
C = "hi",
D = 10,
E,
F = "bye"
}
enum E08 {
A = 10,
B = "hello",
C = A,
D = B,
E = C,
}
// Examples of numeric enum types with only constant members
enum E10 {}
enum E11 {
A = +0,
B,
C
}
enum E12 {
A = 1 << 0,
B = 1 << 1,
C = 1 << 2
}
// Examples of numeric enum types with constant and computed members
enum E20 {
A = "foo".length,
B = A + 1,
C = +"123",
D = Math.sin(1)
}
+10 -1
View File
@@ -23,8 +23,17 @@ enum E10 {
// Enum with computed member intializer of other types
enum E11 {
A = '',
A = true,
B = new Date(),
C = window,
D = {}
}
// Enum with string valued member and computed member initializers
enum E12 {
A = '',
B = new Date(),
C = window,
D = {},
E = 1 + 1,
}
@@ -0,0 +1,99 @@
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
type YesNo = Choice.Yes | Choice.No;
type NoYes = Choice.No | Choice.Yes;
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
function f1() {
var a: YesNo;
var a: NoYes;
var a: Choice.Yes | Choice.No;
var a: Choice.No | Choice.Yes;
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
b = a;
c = a;
c = b;
}
function f3(a: Choice.Yes, b: YesNo) {
var x = a + b;
var y = a == b;
var y = a != b;
var y = a === b;
var y = a !== b;
var y = a > b;
var y = a < b;
var y = a >= b;
var y = a <= b;
var y = !b;
}
declare function g(x: Choice.Yes): string;
declare function g(x: Choice.No): boolean;
declare function g(x: Choice): number;
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
var z1 = g(Choice.Yes);
var z2 = g(Choice.No);
var z3 = g(a);
var z4 = g(b);
var z5 = g(c);
}
function assertNever(x: never): never {
throw new Error("Unexpected value");
}
function f10(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
}
function f11(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
return assertNever(x);
}
function f12(x: UnknownYesNo) {
if (x) {
x;
}
else {
x;
}
}
function f13(x: UnknownYesNo) {
if (x === Choice.Yes) {
x;
}
else {
x;
}
}
type Item =
{ kind: Choice.Yes, a: string } |
{ kind: Choice.No, b: string };
function f20(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
}
function f21(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
return assertNever(x);
}
@@ -0,0 +1,101 @@
// @strictNullChecks: true
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
type YesNo = Choice.Yes | Choice.No;
type NoYes = Choice.No | Choice.Yes;
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
function f1() {
var a: YesNo;
var a: NoYes;
var a: Choice.Yes | Choice.No;
var a: Choice.No | Choice.Yes;
}
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
b = a;
c = a;
c = b;
}
function f3(a: Choice.Yes, b: YesNo) {
var x = a + b;
var y = a == b;
var y = a != b;
var y = a === b;
var y = a !== b;
var y = a > b;
var y = a < b;
var y = a >= b;
var y = a <= b;
var y = !b;
}
declare function g(x: Choice.Yes): string;
declare function g(x: Choice.No): boolean;
declare function g(x: Choice): number;
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
var z1 = g(Choice.Yes);
var z2 = g(Choice.No);
var z3 = g(a);
var z4 = g(b);
var z5 = g(c);
}
function assertNever(x: never): never {
throw new Error("Unexpected value");
}
function f10(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
}
function f11(x: YesNo) {
switch (x) {
case Choice.Yes: return "true";
case Choice.No: return "false";
}
return assertNever(x);
}
function f12(x: UnknownYesNo) {
if (x) {
x;
}
else {
x;
}
}
function f13(x: UnknownYesNo) {
if (x === Choice.Yes) {
x;
}
else {
x;
}
}
type Item =
{ kind: Choice.Yes, a: string } |
{ kind: Choice.No, b: string };
function f20(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
}
function f21(x: Item) {
switch (x.kind) {
case Choice.Yes: return x.a;
case Choice.No: return x.b;
}
return assertNever(x);
}
@@ -0,0 +1,119 @@
const enum Choice { Unknown = "", Yes = "yes", No = "no" };
type Yes = Choice.Yes;
type YesNo = Choice.Yes | Choice.No;
type NoYes = Choice.No | Choice.Yes;
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
function f1(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a = a;
a = b;
a = c;
a = d;
}
function f2(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
b = a;
b = b;
b = c;
b = d;
}
function f3(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
c = a;
c = b;
c = c;
c = d;
}
function f4(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
d = a;
d = b;
d = c;
d = d;
}
function f5(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a = Choice.Unknown;
a = Choice.Yes;
a = Choice.No;
b = Choice.Unknown;
b = Choice.Yes;
b = Choice.No;
c = Choice.Unknown;
c = Choice.Yes;
c = Choice.No;
d = Choice.Unknown;
d = Choice.Yes;
d = Choice.No;
}
function f6(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a === Choice.Unknown;
a === Choice.Yes;
a === Choice.No;
b === Choice.Unknown;
b === Choice.Yes;
b === Choice.No;
c === Choice.Unknown;
c === Choice.Yes;
c === Choice.No;
d === Choice.Unknown;
d === Choice.Yes;
d === Choice.No;
}
function f7(a: Yes, b: YesNo, c: UnknownYesNo, d: Choice) {
a === a;
a === b;
a === c;
a === d;
b === a;
b === b;
b === c;
b === d;
c === a;
c === b;
c === c;
c === d;
d === a;
d === b;
d === c;
d === d;
}
function f10(x: Yes): Yes {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f11(x: YesNo): YesNo {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f12(x: UnknownYesNo): UnknownYesNo {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}
function f13(x: Choice): Choice {
switch (x) {
case Choice.Unknown: return x;
case Choice.Yes: return x;
case Choice.No: return x;
}
return x;
}