mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #11126 from Microsoft/nonWideningLiterals
Non-widening explicit literal types
This commit is contained in:
+152
-45
@@ -2015,6 +2015,10 @@ namespace ts {
|
||||
isExternalModuleAugmentation(node.parent.parent);
|
||||
}
|
||||
|
||||
function literalTypeToString(type: LiteralType) {
|
||||
return type.flags & TypeFlags.StringLiteral ? `"${escapeString((<LiteralType>type).text)}"` : (<LiteralType>type).text;
|
||||
}
|
||||
|
||||
function getSymbolDisplayBuilder(): SymbolDisplayBuilder {
|
||||
|
||||
function getNameOfSymbol(symbol: Symbol): string {
|
||||
@@ -2190,11 +2194,8 @@ namespace ts {
|
||||
else if (type.flags & TypeFlags.Anonymous) {
|
||||
writeAnonymousType(<ObjectType>type, nextFlags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.StringLiteral) {
|
||||
writer.writeStringLiteral(`"${escapeString((<LiteralType>type).text)}"`);
|
||||
}
|
||||
else if (type.flags & TypeFlags.NumberLiteral) {
|
||||
writer.writeStringLiteral((<LiteralType>type).text);
|
||||
else if (type.flags & TypeFlags.StringOrNumberLiteral) {
|
||||
writer.writeStringLiteral(literalTypeToString(<LiteralType>type));
|
||||
}
|
||||
else {
|
||||
// Should never get here
|
||||
@@ -3839,6 +3840,14 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
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 getDeclaredTypeOfEnum(symbol: Symbol): Type {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.declaredType) {
|
||||
@@ -3854,10 +3863,7 @@ namespace ts {
|
||||
const memberSymbol = getSymbolOfNode(member);
|
||||
const value = getEnumMemberValue(member);
|
||||
if (!memberTypes[value]) {
|
||||
const memberType = memberTypes[value] = <EnumLiteralType>createType(TypeFlags.EnumLiteral);
|
||||
memberType.symbol = memberSymbol;
|
||||
memberType.baseType = <EnumType & UnionType>enumType;
|
||||
memberType.text = "" + value;
|
||||
const memberType = memberTypes[value] = createEnumLiteralType(memberSymbol, enumType, "" + value);
|
||||
memberTypeList.push(memberType);
|
||||
}
|
||||
}
|
||||
@@ -5336,6 +5342,9 @@ namespace ts {
|
||||
containsUndefined?: boolean;
|
||||
containsNull?: boolean;
|
||||
containsNonWideningType?: boolean;
|
||||
containsString?: boolean;
|
||||
containsNumber?: boolean;
|
||||
containsStringOrNumberLiteral?: boolean;
|
||||
}
|
||||
|
||||
function binarySearchTypes(types: Type[], type: Type): number {
|
||||
@@ -5363,22 +5372,26 @@ namespace ts {
|
||||
}
|
||||
|
||||
function addTypeToUnion(typeSet: TypeSet, type: Type) {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
const flags = type.flags;
|
||||
if (flags & TypeFlags.Union) {
|
||||
addTypesToUnion(typeSet, (<UnionType>type).types);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Any) {
|
||||
else if (flags & TypeFlags.Any) {
|
||||
typeSet.containsAny = true;
|
||||
}
|
||||
else if (!strictNullChecks && type.flags & TypeFlags.Nullable) {
|
||||
if (type.flags & TypeFlags.Undefined) typeSet.containsUndefined = true;
|
||||
if (type.flags & TypeFlags.Null) typeSet.containsNull = true;
|
||||
if (!(type.flags & TypeFlags.ContainsWideningType)) typeSet.containsNonWideningType = true;
|
||||
else if (!strictNullChecks && flags & TypeFlags.Nullable) {
|
||||
if (flags & TypeFlags.Undefined) typeSet.containsUndefined = true;
|
||||
if (flags & TypeFlags.Null) typeSet.containsNull = true;
|
||||
if (!(flags & TypeFlags.ContainsWideningType)) typeSet.containsNonWideningType = true;
|
||||
}
|
||||
else if (!(type.flags & TypeFlags.Never)) {
|
||||
else if (!(flags & TypeFlags.Never)) {
|
||||
if (flags & TypeFlags.String) typeSet.containsString = true;
|
||||
if (flags & TypeFlags.Number) typeSet.containsNumber = true;
|
||||
if (flags & TypeFlags.StringOrNumberLiteral) typeSet.containsStringOrNumberLiteral = true;
|
||||
const len = typeSet.length;
|
||||
const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearchTypes(typeSet, type);
|
||||
if (index < 0) {
|
||||
if (!(type.flags & TypeFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
|
||||
if (!(flags & TypeFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
|
||||
typeSet.splice(~index, 0, type);
|
||||
}
|
||||
}
|
||||
@@ -5411,7 +5424,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function removeSubtypes(types: Type[]) {
|
||||
function removeSubtypes(types: TypeSet) {
|
||||
let i = types.length;
|
||||
while (i > 0) {
|
||||
i--;
|
||||
@@ -5421,6 +5434,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function removeRedundantLiteralTypes(types: TypeSet) {
|
||||
let i = types.length;
|
||||
while (i > 0) {
|
||||
i--;
|
||||
const t = types[i];
|
||||
const remove =
|
||||
t.flags & TypeFlags.StringLiteral && types.containsString ||
|
||||
t.flags & TypeFlags.NumberLiteral && types.containsNumber ||
|
||||
t.flags & TypeFlags.StringOrNumberLiteral && t.flags & TypeFlags.FreshLiteral && containsType(types, (<LiteralType>t).regularType);
|
||||
if (remove) {
|
||||
orderedRemoveItemAt(types, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We sort and deduplicate the constituent types based on object identity. If the subtypeReduction
|
||||
// flag is specified we also reduce the constituent type set to only include types that aren't subtypes
|
||||
// of other types. Subtype reduction is expensive for large union types and is possible only when union
|
||||
@@ -5443,6 +5471,9 @@ namespace ts {
|
||||
if (subtypeReduction) {
|
||||
removeSubtypes(typeSet);
|
||||
}
|
||||
else if (typeSet.containsStringOrNumberLiteral) {
|
||||
removeRedundantLiteralTypes(typeSet);
|
||||
}
|
||||
if (typeSet.length === 0) {
|
||||
return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType :
|
||||
typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType :
|
||||
@@ -5554,6 +5585,22 @@ namespace ts {
|
||||
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);
|
||||
freshType.regularType = <LiteralType>type;
|
||||
(<LiteralType>type).freshType = freshType;
|
||||
}
|
||||
return (<LiteralType>type).freshType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function getRegularTypeOfLiteralType(type: Type) {
|
||||
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;
|
||||
return map[text] || (map[text] = createLiteralType(flags, text));
|
||||
@@ -5562,7 +5609,7 @@ namespace ts {
|
||||
function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = checkExpression(node.literal);
|
||||
links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
@@ -6274,7 +6321,7 @@ namespace ts {
|
||||
if ((source.flags & TypeFlags.Number | source.flags & TypeFlags.NumberLiteral) && target.flags & TypeFlags.EnumLike) return true;
|
||||
if (source.flags & TypeFlags.EnumLiteral &&
|
||||
target.flags & TypeFlags.EnumLiteral &&
|
||||
(<LiteralType>source).text === (<LiteralType>target).text &&
|
||||
(<EnumLiteralType>source).text === (<EnumLiteralType>target).text &&
|
||||
isEnumTypeRelatedTo((<EnumLiteralType>source).baseType, (<EnumLiteralType>target).baseType, errorReporter)) {
|
||||
return true;
|
||||
}
|
||||
@@ -6288,6 +6335,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>) {
|
||||
if (source.flags & TypeFlags.StringOrNumberLiteral && source.flags & TypeFlags.FreshLiteral) {
|
||||
source = (<LiteralType>source).regularType;
|
||||
}
|
||||
if (target.flags & TypeFlags.StringOrNumberLiteral && target.flags & TypeFlags.FreshLiteral) {
|
||||
target = (<LiteralType>target).regularType;
|
||||
}
|
||||
if (source === target || relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) {
|
||||
return true;
|
||||
}
|
||||
@@ -6385,6 +6438,12 @@ namespace ts {
|
||||
// Ternary.False if they are not related.
|
||||
function isRelatedTo(source: Type, target: Type, reportErrors?: boolean, headMessage?: DiagnosticMessage): Ternary {
|
||||
let result: Ternary;
|
||||
if (source.flags & TypeFlags.StringOrNumberLiteral && source.flags & TypeFlags.FreshLiteral) {
|
||||
source = (<LiteralType>source).regularType;
|
||||
}
|
||||
if (target.flags & TypeFlags.StringOrNumberLiteral && target.flags & TypeFlags.FreshLiteral) {
|
||||
target = (<LiteralType>target).regularType;
|
||||
}
|
||||
// both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
|
||||
if (source === target) return Ternary.True;
|
||||
|
||||
@@ -6394,7 +6453,7 @@ namespace ts {
|
||||
|
||||
if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
|
||||
|
||||
if (source.flags & TypeFlags.FreshObjectLiteral) {
|
||||
if (source.flags & TypeFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) {
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
reportRelationError(headMessage, source, target);
|
||||
@@ -7303,6 +7362,15 @@ namespace ts {
|
||||
type;
|
||||
}
|
||||
|
||||
function getWidenedLiteralType(type: Type): Type {
|
||||
return 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(map((<UnionType>type).types, getWidenedLiteralType)) :
|
||||
type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Type was written as a tuple type literal.
|
||||
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
|
||||
@@ -7324,8 +7392,8 @@ 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 ? type === emptyStringType ? TypeFlags.StringLiteral : 0 :
|
||||
type.flags & TypeFlags.NumberLiteral ? type === zeroType ? TypeFlags.NumberLiteral : 0 :
|
||||
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;
|
||||
}
|
||||
@@ -7392,7 +7460,7 @@ namespace ts {
|
||||
* Leave signatures alone since they are not subject to the check.
|
||||
*/
|
||||
function getRegularTypeOfObjectLiteral(type: Type): Type {
|
||||
if (!(type.flags & TypeFlags.FreshObjectLiteral)) {
|
||||
if (!(type.flags & TypeFlags.ObjectLiteral && type.flags & TypeFlags.FreshLiteral)) {
|
||||
return type;
|
||||
}
|
||||
const regularType = (<FreshObjectLiteralType>type).regularType;
|
||||
@@ -7408,7 +7476,7 @@ namespace ts {
|
||||
resolved.constructSignatures,
|
||||
resolved.stringIndexInfo,
|
||||
resolved.numberIndexInfo);
|
||||
regularNew.flags = resolved.flags & ~TypeFlags.FreshObjectLiteral;
|
||||
regularNew.flags = resolved.flags & ~TypeFlags.FreshLiteral;
|
||||
(<FreshObjectLiteralType>type).regularType = regularNew;
|
||||
return regularNew;
|
||||
}
|
||||
@@ -7859,7 +7927,7 @@ namespace ts {
|
||||
const widenLiteralTypes = context.inferences[index].topLevel &&
|
||||
!hasPrimitiveConstraint(signature.typeParameters[index]) &&
|
||||
(context.inferences[index].isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), signature.typeParameters[index]));
|
||||
const baseInferences = widenLiteralTypes ? map(inferences, getBaseTypeOfLiteralType) : inferences;
|
||||
const baseInferences = widenLiteralTypes ? map(inferences, getWidenedLiteralType) : inferences;
|
||||
// Infer widened union or supertype, or the unknown type for no common supertype
|
||||
const unionOrSuperType = context.inferUnionTypes ? getUnionType(baseInferences, /*subtypeReduction*/ true) : getCommonSupertype(baseInferences);
|
||||
inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType;
|
||||
@@ -8110,14 +8178,14 @@ namespace ts {
|
||||
}
|
||||
if (flags & TypeFlags.StringLiteral) {
|
||||
return strictNullChecks ?
|
||||
type === emptyStringType ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts :
|
||||
type === emptyStringType ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts;
|
||||
(<LiteralType>type).text === "" ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts :
|
||||
(<LiteralType>type).text === "" ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts;
|
||||
}
|
||||
if (flags & (TypeFlags.Number | TypeFlags.Enum)) {
|
||||
return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts;
|
||||
}
|
||||
if (flags & (TypeFlags.NumberLiteral | TypeFlags.EnumLiteral)) {
|
||||
const isZero = type === zeroType || type.flags & TypeFlags.EnumLiteral && (<LiteralType>type).text === "0";
|
||||
const isZero = (<LiteralType>type).text === "0";
|
||||
return strictNullChecks ?
|
||||
isZero ? TypeFacts.ZeroStrictFacts : TypeFacts.NonZeroStrictFacts :
|
||||
isZero ? TypeFacts.ZeroFacts : TypeFacts.NonZeroFacts;
|
||||
@@ -8290,7 +8358,7 @@ namespace ts {
|
||||
|
||||
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
|
||||
if (clause.kind === SyntaxKind.CaseClause) {
|
||||
const caseType = checkExpression((<CaseClause>clause).expression);
|
||||
const caseType = getRegularTypeOfLiteralType(checkExpression((<CaseClause>clause).expression));
|
||||
return isUnitType(caseType) ? caseType : undefined;
|
||||
}
|
||||
return neverType;
|
||||
@@ -8671,7 +8739,11 @@ namespace ts {
|
||||
const narrowedType = filterType(type, t => areTypesComparable(t, valueType));
|
||||
return narrowedType.flags & TypeFlags.Never ? type : narrowedType;
|
||||
}
|
||||
return isUnitType(valueType) ? filterType(type, t => t !== valueType) : type;
|
||||
if (isUnitType(valueType)) {
|
||||
const regularType = getRegularTypeOfLiteralType(valueType);
|
||||
return filterType(type, t => getRegularTypeOfLiteralType(t) !== regularType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function narrowTypeByTypeof(type: Type, typeOfExpr: TypeOfExpression, operator: SyntaxKind, literal: LiteralExpression, assumeTrue: boolean): Type {
|
||||
@@ -8716,7 +8788,7 @@ namespace ts {
|
||||
if (!hasDefaultClause) {
|
||||
return caseType;
|
||||
}
|
||||
const defaultType = filterType(type, t => !(isUnitType(t) && contains(switchTypes, t)));
|
||||
const defaultType = filterType(type, t => !(isUnitType(t) && contains(switchTypes, getRegularTypeOfLiteralType(t))));
|
||||
return caseType.flags & TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]);
|
||||
}
|
||||
|
||||
@@ -9551,14 +9623,14 @@ namespace ts {
|
||||
if (parameter.dotDotDotToken) {
|
||||
const restTypes: Type[] = [];
|
||||
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
|
||||
restTypes.push(getBaseTypeOfLiteralType(checkExpression(iife.arguments[i])));
|
||||
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
|
||||
}
|
||||
return createArrayType(getUnionType(restTypes));
|
||||
}
|
||||
const links = getNodeLinks(iife);
|
||||
const cached = links.resolvedSignature;
|
||||
links.resolvedSignature = anySignature;
|
||||
const type = getBaseTypeOfLiteralType(checkExpression(iife.arguments[indexOfParameter]));
|
||||
const type = getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter]));
|
||||
links.resolvedSignature = cached;
|
||||
return type;
|
||||
}
|
||||
@@ -10290,7 +10362,7 @@ namespace ts {
|
||||
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.String) : undefined;
|
||||
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.Number) : undefined;
|
||||
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshObjectLiteral;
|
||||
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral;
|
||||
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags) | (patternWithComputedProperties ? TypeFlags.ObjectLiteralPatternWithComputedProperties : 0);
|
||||
if (inDestructuringPattern) {
|
||||
result.pattern = node;
|
||||
@@ -12660,7 +12732,7 @@ namespace ts {
|
||||
reportErrorsFromWidening(func, type);
|
||||
}
|
||||
if (isUnitType(type) && !(contextualSignature && isLiteralContextualType(getReturnTypeOfSignature(contextualSignature)))) {
|
||||
type = getBaseTypeOfLiteralType(type);
|
||||
type = getWidenedLiteralType(type);
|
||||
}
|
||||
|
||||
const widenedType = getWidenedType(type);
|
||||
@@ -13044,7 +13116,7 @@ namespace ts {
|
||||
return silentNeverType;
|
||||
}
|
||||
if (node.operator === SyntaxKind.MinusToken && node.operand.kind === SyntaxKind.NumericLiteral) {
|
||||
return getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>node.operand).text);
|
||||
return getFreshTypeOfLiteralType(getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>node.operand).text));
|
||||
}
|
||||
switch (node.operator) {
|
||||
case SyntaxKind.PlusToken:
|
||||
@@ -13683,12 +13755,13 @@ namespace ts {
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
return getLiteralTypeForText(TypeFlags.StringLiteral, (<LiteralExpression>node).text);
|
||||
return getFreshTypeOfLiteralType(getLiteralTypeForText(TypeFlags.StringLiteral, (<LiteralExpression>node).text));
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return getLiteralTypeForText(TypeFlags.NumberLiteral, (<LiteralExpression>node).text);
|
||||
return getFreshTypeOfLiteralType(getLiteralTypeForText(TypeFlags.NumberLiteral, (<LiteralExpression>node).text));
|
||||
case SyntaxKind.TrueKeyword:
|
||||
return trueType;
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return node.kind === SyntaxKind.TrueKeyword ? trueType : falseType;
|
||||
return falseType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13736,7 +13809,7 @@ namespace ts {
|
||||
const type = checkExpressionCached(declaration.initializer);
|
||||
return getCombinedNodeFlags(declaration) & NodeFlags.Const ||
|
||||
getCombinedModifierFlags(declaration) & ModifierFlags.Readonly ||
|
||||
isTypeAssertion(declaration.initializer) ? type : getBaseTypeOfLiteralType(type);
|
||||
isTypeAssertion(declaration.initializer) ? type : getWidenedLiteralType(type);
|
||||
}
|
||||
|
||||
function isLiteralContextualType(contextualType: Type) {
|
||||
@@ -13758,7 +13831,7 @@ namespace ts {
|
||||
|
||||
function checkExpressionForMutableLocation(node: Expression, contextualMapper?: TypeMapper): Type {
|
||||
const type = checkExpression(node, contextualMapper);
|
||||
return isTypeAssertion(node) || isLiteralContextualType(getContextualType(node)) ? type : getBaseTypeOfLiteralType(type);
|
||||
return isTypeAssertion(node) || isLiteralContextualType(getContextualType(node)) ? type : getWidenedLiteralType(type);
|
||||
}
|
||||
|
||||
function checkPropertyAssignment(node: PropertyAssignment, contextualMapper?: TypeMapper): Type {
|
||||
@@ -18473,7 +18546,7 @@ namespace ts {
|
||||
if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
|
||||
expr = <Expression>expr.parent;
|
||||
}
|
||||
return checkExpression(expr);
|
||||
return getRegularTypeOfLiteralType(checkExpression(expr));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18884,7 +18957,7 @@ namespace ts {
|
||||
// Get type of the symbol if this is the valid symbol otherwise get type at location
|
||||
const symbol = getSymbolOfNode(declaration);
|
||||
const type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
|
||||
? getTypeOfSymbol(symbol)
|
||||
? getWidenedLiteralType(getTypeOfSymbol(symbol))
|
||||
: unknownType;
|
||||
|
||||
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
|
||||
@@ -18944,6 +19017,19 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isLiteralConstDeclaration(node: VariableDeclaration): boolean {
|
||||
if (isConst(node)) {
|
||||
const type = getTypeOfSymbol(getSymbolOfNode(node));
|
||||
return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter) {
|
||||
const type = getTypeOfSymbol(getSymbolOfNode(node));
|
||||
writer.writeStringLiteral(literalTypeToString(<LiteralType>type));
|
||||
}
|
||||
|
||||
function createResolver(): EmitResolver {
|
||||
// this variable and functions that use it are deliberately moved here from the outer scope
|
||||
// to avoid scope pollution
|
||||
@@ -18988,7 +19074,9 @@ namespace ts {
|
||||
isArgumentsLocalBinding,
|
||||
getExternalModuleFileFromDeclaration,
|
||||
getTypeReferenceDirectivesForEntityName,
|
||||
getTypeReferenceDirectivesForSymbol
|
||||
getTypeReferenceDirectivesForSymbol,
|
||||
isLiteralConstDeclaration,
|
||||
writeLiteralConstValue
|
||||
};
|
||||
|
||||
// defined here to avoid outer scope pollution
|
||||
@@ -20134,10 +20222,29 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isStringOrNumberLiteralExpression(expr: Expression) {
|
||||
return expr.kind === SyntaxKind.StringLiteral || expr.kind === SyntaxKind.NumericLiteral ||
|
||||
expr.kind === SyntaxKind.PrefixUnaryExpression && (<PrefixUnaryExpression>expr).operator === SyntaxKind.MinusToken &&
|
||||
(<PrefixUnaryExpression>expr).operand.kind === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
||||
function checkGrammarVariableDeclaration(node: VariableDeclaration) {
|
||||
if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) {
|
||||
if (isInAmbientContext(node)) {
|
||||
if (node.initializer) {
|
||||
if (isConst(node) && !node.type) {
|
||||
if (!isStringOrNumberLiteralExpression(node.initializer)) {
|
||||
return grammarErrorOnNode(node.initializer, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Error on equals token which immediate precedes the initializer
|
||||
const equalsTokenLength = "=".length;
|
||||
return grammarErrorAtPos(getSourceFileOfNode(node), node.initializer.pos - equalsTokenLength,
|
||||
equalsTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
|
||||
}
|
||||
}
|
||||
if (node.initializer && !(isConst(node) && isStringOrNumberLiteralExpression(node.initializer))) {
|
||||
// Error on equals token which immediate precedes the initializer
|
||||
const equalsTokenLength = "=".length;
|
||||
return grammarErrorAtPos(getSourceFileOfNode(node), node.initializer.pos - equalsTokenLength,
|
||||
|
||||
@@ -1142,6 +1142,10 @@ namespace ts {
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
|
||||
emitTypeOfVariableDeclarationFromTypeLiteral(node);
|
||||
}
|
||||
else if (resolver.isLiteralConstDeclaration(node)) {
|
||||
write(" = ");
|
||||
resolver.writeLiteralConstValue(node, writer);
|
||||
}
|
||||
else if (!hasModifier(node, ModifierFlags.Private)) {
|
||||
writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError);
|
||||
}
|
||||
|
||||
@@ -819,6 +819,10 @@
|
||||
"category": "Error",
|
||||
"code": 1253
|
||||
},
|
||||
"A 'const' initializer in an ambient context must be a string or numeric literal.": {
|
||||
"category": "Error",
|
||||
"code": 1254
|
||||
},
|
||||
"'with' statements are not allowed in an async function block.": {
|
||||
"category": "Error",
|
||||
"code": 1300
|
||||
|
||||
+10
-4
@@ -2167,6 +2167,8 @@ namespace ts {
|
||||
getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile;
|
||||
getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[];
|
||||
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[];
|
||||
isLiteralConstDeclaration(node: VariableDeclaration): boolean;
|
||||
writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter): void;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@@ -2383,7 +2385,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
ObjectLiteral = 1 << 23, // Originates in an object literal
|
||||
/* @internal */
|
||||
FreshObjectLiteral = 1 << 24, // Fresh object literal type
|
||||
FreshLiteral = 1 << 24, // Fresh literal type
|
||||
/* @internal */
|
||||
ContainsWideningType = 1 << 25, // Type is or contains undefined or null widening type
|
||||
/* @internal */
|
||||
@@ -2396,6 +2398,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
Nullable = Undefined | Null,
|
||||
Literal = StringLiteral | NumberLiteral | BooleanLiteral | EnumLiteral,
|
||||
StringOrNumberLiteral = StringLiteral | NumberLiteral,
|
||||
/* @internal */
|
||||
DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null,
|
||||
PossiblyFalsy = DefinitelyFalsy | String | Number | Boolean,
|
||||
@@ -2437,12 +2440,15 @@ namespace ts {
|
||||
/* @internal */
|
||||
// Intrinsic types (TypeFlags.Intrinsic)
|
||||
export interface IntrinsicType extends Type {
|
||||
intrinsicName: string; // Name of intrinsic type
|
||||
intrinsicName: string; // Name of intrinsic type
|
||||
}
|
||||
|
||||
// String literal types (TypeFlags.StringLiteral)
|
||||
// Numeric literal types (TypeFlags.NumberLiteral)
|
||||
export interface LiteralType extends Type {
|
||||
text: string; // Text of string literal
|
||||
text: string; // Text of literal
|
||||
freshType?: LiteralType; // Fresh version of type
|
||||
regularType?: LiteralType; // Regular version of type
|
||||
}
|
||||
|
||||
// Enum types (TypeFlags.Enum)
|
||||
@@ -2452,7 +2458,7 @@ namespace ts {
|
||||
|
||||
// Enum types (TypeFlags.EnumLiteral)
|
||||
export interface EnumLiteralType extends LiteralType {
|
||||
baseType: EnumType & UnionType;
|
||||
baseType: EnumType & UnionType; // Base enum type
|
||||
}
|
||||
|
||||
// Object types (TypeFlags.ObjectType)
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//// [ambientConstLiterals.ts]
|
||||
|
||||
function f<T>(x: T): T {
|
||||
return x;
|
||||
}
|
||||
|
||||
enum E { A, B, C }
|
||||
|
||||
const c1 = "abc";
|
||||
const c2 = 123;
|
||||
const c3 = c1;
|
||||
const c4 = c2;
|
||||
const c5 = f(123);
|
||||
const c6 = f(-123);
|
||||
const c7 = true;
|
||||
const c8 = E.A;
|
||||
const c9 = { x: "abc" };
|
||||
const c10 = [123];
|
||||
const c11 = "abc" + "def";
|
||||
const c12 = 123 + 456;
|
||||
const c13 = Math.random() > 0.5 ? "abc" : "def";
|
||||
const c14 = Math.random() > 0.5 ? 123 : 456;
|
||||
|
||||
//// [ambientConstLiterals.js]
|
||||
function f(x) {
|
||||
return x;
|
||||
}
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
E[E["B"] = 1] = "B";
|
||||
E[E["C"] = 2] = "C";
|
||||
})(E || (E = {}));
|
||||
var c1 = "abc";
|
||||
var c2 = 123;
|
||||
var c3 = c1;
|
||||
var c4 = c2;
|
||||
var c5 = f(123);
|
||||
var c6 = f(-123);
|
||||
var c7 = true;
|
||||
var c8 = E.A;
|
||||
var c9 = { x: "abc" };
|
||||
var c10 = [123];
|
||||
var c11 = "abc" + "def";
|
||||
var c12 = 123 + 456;
|
||||
var c13 = Math.random() > 0.5 ? "abc" : "def";
|
||||
var c14 = Math.random() > 0.5 ? 123 : 456;
|
||||
|
||||
|
||||
//// [ambientConstLiterals.d.ts]
|
||||
declare function f<T>(x: T): T;
|
||||
declare enum E {
|
||||
A = 0,
|
||||
B = 1,
|
||||
C = 2,
|
||||
}
|
||||
declare const c1 = "abc";
|
||||
declare const c2 = 123;
|
||||
declare const c3 = "abc";
|
||||
declare const c4 = 123;
|
||||
declare const c5 = 123;
|
||||
declare const c6 = -123;
|
||||
declare const c7: boolean;
|
||||
declare const c8: E;
|
||||
declare const c9: {
|
||||
x: string;
|
||||
};
|
||||
declare const c10: number[];
|
||||
declare const c11: string;
|
||||
declare const c12: number;
|
||||
declare const c13: string;
|
||||
declare const c14: number;
|
||||
@@ -0,0 +1,75 @@
|
||||
=== tests/cases/compiler/ambientConstLiterals.ts ===
|
||||
|
||||
function f<T>(x: T): T {
|
||||
>f : Symbol(f, Decl(ambientConstLiterals.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(ambientConstLiterals.ts, 1, 11))
|
||||
>x : Symbol(x, Decl(ambientConstLiterals.ts, 1, 14))
|
||||
>T : Symbol(T, Decl(ambientConstLiterals.ts, 1, 11))
|
||||
>T : Symbol(T, Decl(ambientConstLiterals.ts, 1, 11))
|
||||
|
||||
return x;
|
||||
>x : Symbol(x, Decl(ambientConstLiterals.ts, 1, 14))
|
||||
}
|
||||
|
||||
enum E { A, B, C }
|
||||
>E : Symbol(E, Decl(ambientConstLiterals.ts, 3, 1))
|
||||
>A : Symbol(E.A, Decl(ambientConstLiterals.ts, 5, 8))
|
||||
>B : Symbol(E.B, Decl(ambientConstLiterals.ts, 5, 11))
|
||||
>C : Symbol(E.C, Decl(ambientConstLiterals.ts, 5, 14))
|
||||
|
||||
const c1 = "abc";
|
||||
>c1 : Symbol(c1, Decl(ambientConstLiterals.ts, 7, 5))
|
||||
|
||||
const c2 = 123;
|
||||
>c2 : Symbol(c2, Decl(ambientConstLiterals.ts, 8, 5))
|
||||
|
||||
const c3 = c1;
|
||||
>c3 : Symbol(c3, Decl(ambientConstLiterals.ts, 9, 5))
|
||||
>c1 : Symbol(c1, Decl(ambientConstLiterals.ts, 7, 5))
|
||||
|
||||
const c4 = c2;
|
||||
>c4 : Symbol(c4, Decl(ambientConstLiterals.ts, 10, 5))
|
||||
>c2 : Symbol(c2, Decl(ambientConstLiterals.ts, 8, 5))
|
||||
|
||||
const c5 = f(123);
|
||||
>c5 : Symbol(c5, Decl(ambientConstLiterals.ts, 11, 5))
|
||||
>f : Symbol(f, Decl(ambientConstLiterals.ts, 0, 0))
|
||||
|
||||
const c6 = f(-123);
|
||||
>c6 : Symbol(c6, Decl(ambientConstLiterals.ts, 12, 5))
|
||||
>f : Symbol(f, Decl(ambientConstLiterals.ts, 0, 0))
|
||||
|
||||
const c7 = true;
|
||||
>c7 : Symbol(c7, Decl(ambientConstLiterals.ts, 13, 5))
|
||||
|
||||
const c8 = E.A;
|
||||
>c8 : Symbol(c8, Decl(ambientConstLiterals.ts, 14, 5))
|
||||
>E.A : Symbol(E.A, Decl(ambientConstLiterals.ts, 5, 8))
|
||||
>E : Symbol(E, Decl(ambientConstLiterals.ts, 3, 1))
|
||||
>A : Symbol(E.A, Decl(ambientConstLiterals.ts, 5, 8))
|
||||
|
||||
const c9 = { x: "abc" };
|
||||
>c9 : Symbol(c9, Decl(ambientConstLiterals.ts, 15, 5))
|
||||
>x : Symbol(x, Decl(ambientConstLiterals.ts, 15, 12))
|
||||
|
||||
const c10 = [123];
|
||||
>c10 : Symbol(c10, Decl(ambientConstLiterals.ts, 16, 5))
|
||||
|
||||
const c11 = "abc" + "def";
|
||||
>c11 : Symbol(c11, Decl(ambientConstLiterals.ts, 17, 5))
|
||||
|
||||
const c12 = 123 + 456;
|
||||
>c12 : Symbol(c12, Decl(ambientConstLiterals.ts, 18, 5))
|
||||
|
||||
const c13 = Math.random() > 0.5 ? "abc" : "def";
|
||||
>c13 : Symbol(c13, Decl(ambientConstLiterals.ts, 19, 5))
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
const c14 = Math.random() > 0.5 ? 123 : 456;
|
||||
>c14 : Symbol(c14, Decl(ambientConstLiterals.ts, 20, 5))
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
=== tests/cases/compiler/ambientConstLiterals.ts ===
|
||||
|
||||
function f<T>(x: T): T {
|
||||
>f : <T>(x: T) => T
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
return x;
|
||||
>x : T
|
||||
}
|
||||
|
||||
enum E { A, B, C }
|
||||
>E : E
|
||||
>A : E.A
|
||||
>B : E.B
|
||||
>C : E.C
|
||||
|
||||
const c1 = "abc";
|
||||
>c1 : "abc"
|
||||
>"abc" : "abc"
|
||||
|
||||
const c2 = 123;
|
||||
>c2 : 123
|
||||
>123 : 123
|
||||
|
||||
const c3 = c1;
|
||||
>c3 : "abc"
|
||||
>c1 : "abc"
|
||||
|
||||
const c4 = c2;
|
||||
>c4 : 123
|
||||
>c2 : 123
|
||||
|
||||
const c5 = f(123);
|
||||
>c5 : 123
|
||||
>f(123) : 123
|
||||
>f : <T>(x: T) => T
|
||||
>123 : 123
|
||||
|
||||
const c6 = f(-123);
|
||||
>c6 : -123
|
||||
>f(-123) : -123
|
||||
>f : <T>(x: T) => T
|
||||
>-123 : -123
|
||||
>123 : 123
|
||||
|
||||
const c7 = true;
|
||||
>c7 : true
|
||||
>true : true
|
||||
|
||||
const c8 = E.A;
|
||||
>c8 : E.A
|
||||
>E.A : E.A
|
||||
>E : typeof E
|
||||
>A : E.A
|
||||
|
||||
const c9 = { x: "abc" };
|
||||
>c9 : { x: string; }
|
||||
>{ x: "abc" } : { x: string; }
|
||||
>x : string
|
||||
>"abc" : "abc"
|
||||
|
||||
const c10 = [123];
|
||||
>c10 : number[]
|
||||
>[123] : number[]
|
||||
>123 : 123
|
||||
|
||||
const c11 = "abc" + "def";
|
||||
>c11 : string
|
||||
>"abc" + "def" : string
|
||||
>"abc" : "abc"
|
||||
>"def" : "def"
|
||||
|
||||
const c12 = 123 + 456;
|
||||
>c12 : number
|
||||
>123 + 456 : number
|
||||
>123 : 123
|
||||
>456 : 456
|
||||
|
||||
const c13 = Math.random() > 0.5 ? "abc" : "def";
|
||||
>c13 : "abc" | "def"
|
||||
>Math.random() > 0.5 ? "abc" : "def" : "abc" | "def"
|
||||
>Math.random() > 0.5 : boolean
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
>0.5 : 0.5
|
||||
>"abc" : "abc"
|
||||
>"def" : "def"
|
||||
|
||||
const c14 = Math.random() > 0.5 ? 123 : 456;
|
||||
>c14 : 123 | 456
|
||||
>Math.random() > 0.5 ? 123 : 456 : 123 | 456
|
||||
>Math.random() > 0.5 : boolean
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
>0.5 : 0.5
|
||||
>123 : 123
|
||||
>456 : 456
|
||||
|
||||
@@ -46,7 +46,7 @@ class parser {
|
||||
>this : this
|
||||
>options : IOptions[]
|
||||
>sort : (compareFn?: (a: IOptions, b: IOptions) => number) => IOptions[]
|
||||
>function(a, b) { var aName = a.name.toLowerCase(); var bName = b.name.toLowerCase(); if (aName > bName) { return 1; } else if (aName < bName) { return -1; } else { return 0; } } : (a: IOptions, b: IOptions) => 0 | 1 | -1
|
||||
>function(a, b) { var aName = a.name.toLowerCase(); var bName = b.name.toLowerCase(); if (aName > bName) { return 1; } else if (aName < bName) { return -1; } else { return 0; } } : (a: IOptions, b: IOptions) => 1 | -1 | 0
|
||||
>a : IOptions
|
||||
>b : IOptions
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ var derived2: Derived2;
|
||||
|
||||
var r2 = true ? 1 : '';
|
||||
>r2 : string | number
|
||||
>true ? 1 : '' : "" | 1
|
||||
>true ? 1 : '' : 1 | ""
|
||||
>true : true
|
||||
>1 : 1
|
||||
>'' : ""
|
||||
|
||||
@@ -19,7 +19,7 @@ declare function foo<T>(obj: I<T>): T
|
||||
foo({
|
||||
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[]
|
||||
>foo : <T>(obj: I<T>) => T
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | 0 | (() => void) | number[]; [x: number]: 0 | (() => void) | number[]; 0: () => void; p: ""; }
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; 0: () => void; p: ""; }
|
||||
|
||||
p: "",
|
||||
>p : string
|
||||
|
||||
@@ -19,7 +19,7 @@ declare function foo<T>(obj: I<T>): T
|
||||
foo({
|
||||
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[]
|
||||
>foo : <T>(obj: I<T>) => T
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | 0 | (() => void) | number[]; [x: number]: 0 | (() => void) | number[]; 0: () => void; p: ""; }
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; 0: () => void; p: ""; }
|
||||
|
||||
p: "",
|
||||
>p : string
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
tests/cases/compiler/conditionalExpression1.ts(1,5): error TS2322: Type '"" | 1' is not assignable to type 'boolean'.
|
||||
Type '""' is not assignable to type 'boolean'.
|
||||
tests/cases/compiler/conditionalExpression1.ts(1,5): error TS2322: Type '1 | ""' is not assignable to type 'boolean'.
|
||||
Type '1' is not assignable to type 'boolean'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/conditionalExpression1.ts (1 errors) ====
|
||||
var x: boolean = (true ? 1 : ""); // should be an error
|
||||
~
|
||||
!!! error TS2322: Type '"" | 1' is not assignable to type 'boolean'.
|
||||
!!! error TS2322: Type '""' is not assignable to type 'boolean'.
|
||||
!!! error TS2322: Type '1 | ""' is not assignable to type 'boolean'.
|
||||
!!! error TS2322: Type '1' is not assignable to type 'boolean'.
|
||||
@@ -16,7 +16,7 @@ var b = false ? undefined : 0;
|
||||
|
||||
var c = false ? 1 : 0;
|
||||
>c : number
|
||||
>false ? 1 : 0 : 0 | 1
|
||||
>false ? 1 : 0 : 1 | 0
|
||||
>false : false
|
||||
>1 : 1
|
||||
>0 : 0
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(3,27): error TS1039: Initializers are not allowed in ambient contexts.
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(4,26): error TS1039: Initializers are not allowed in ambient contexts.
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(5,18): error TS1039: Initializers are not allowed in ambient contexts.
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(5,20): error TS1254: A 'const' initializer in an ambient context must be a string or numeric literal.
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(5,37): error TS1039: Initializers are not allowed in ambient contexts.
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(5,51): error TS1039: Initializers are not allowed in ambient contexts.
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(8,14): error TS1039: Initializers are not allowed in ambient contexts.
|
||||
tests/cases/compiler/constDeclarations-ambient-errors.ts(9,22): error TS1039: Initializers are not allowed in ambient contexts.
|
||||
|
||||
|
||||
==== tests/cases/compiler/constDeclarations-ambient-errors.ts (7 errors) ====
|
||||
==== tests/cases/compiler/constDeclarations-ambient-errors.ts (6 errors) ====
|
||||
|
||||
// error: no intialization expected in ambient declarations
|
||||
declare const c1: boolean = true;
|
||||
@@ -17,8 +16,8 @@ tests/cases/compiler/constDeclarations-ambient-errors.ts(9,22): error TS1039: In
|
||||
~
|
||||
!!! error TS1039: Initializers are not allowed in ambient contexts.
|
||||
declare const c3 = null, c4 :string = "", c5: any = 0;
|
||||
~
|
||||
!!! error TS1039: Initializers are not allowed in ambient contexts.
|
||||
~~~~
|
||||
!!! error TS1254: A 'const' initializer in an ambient context must be a string or numeric literal.
|
||||
~
|
||||
!!! error TS1039: Initializers are not allowed in ambient contexts.
|
||||
~
|
||||
@@ -26,8 +25,6 @@ tests/cases/compiler/constDeclarations-ambient-errors.ts(9,22): error TS1039: In
|
||||
|
||||
declare module M {
|
||||
const c6 = 0;
|
||||
~
|
||||
!!! error TS1039: Initializers are not allowed in ambient contexts.
|
||||
const c7: number = 7;
|
||||
~
|
||||
!!! error TS1039: Initializers are not allowed in ambient contexts.
|
||||
|
||||
@@ -25,6 +25,6 @@ for (const c5 = 0, c6 = 0; c5 < c6;) {
|
||||
|
||||
|
||||
//// [constDeclarations.d.ts]
|
||||
declare const c1: false;
|
||||
declare const c1: boolean;
|
||||
declare const c2: number;
|
||||
declare const c3: 0, c4: string, c5: any;
|
||||
declare const c3 = 0, c4: string, c5: any;
|
||||
|
||||
@@ -20,7 +20,7 @@ var M;
|
||||
|
||||
//// [constDeclarations2.d.ts]
|
||||
declare module M {
|
||||
const c1: false;
|
||||
const c1: boolean;
|
||||
const c2: number;
|
||||
const c3: 0, c4: string, c5: any;
|
||||
const c3 = 0, c4: string, c5: any;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ var y = [() => new c()];
|
||||
var k: (() => c) | string = (() => new c()) || "";
|
||||
>k : string | (() => c)
|
||||
>c : c
|
||||
>(() => new c()) || "" : "" | (() => c)
|
||||
>(() => new c()) || "" : (() => c) | ""
|
||||
>(() => new c()) : () => c
|
||||
>() => new c() : () => c
|
||||
>new c() : c
|
||||
|
||||
@@ -45,7 +45,7 @@ var Foo = (function () {
|
||||
|
||||
|
||||
//// [declarationEmitClassMemberNameConflict2.d.ts]
|
||||
declare const Bar: "bar";
|
||||
declare const Bar = "bar";
|
||||
declare enum Hello {
|
||||
World = 0,
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// it is an error if there is no single BCT, these are error cases
|
||||
|
||||
function f1() {
|
||||
>f1 : () => "" | 1
|
||||
>f1 : () => 1 | ""
|
||||
|
||||
if (true) {
|
||||
>true : true
|
||||
@@ -19,7 +19,7 @@ function f1() {
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : () => "" | 1 | 2
|
||||
>f2 : () => 1 | "" | 2
|
||||
|
||||
if (true) {
|
||||
>true : true
|
||||
@@ -40,7 +40,7 @@ function f2() {
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : () => "" | 1
|
||||
>f3 : () => 1 | ""
|
||||
|
||||
try {
|
||||
return 1;
|
||||
@@ -55,7 +55,7 @@ function f3() {
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : () => "" | 1
|
||||
>f4 : () => 1 | ""
|
||||
|
||||
try {
|
||||
return 1;
|
||||
@@ -72,7 +72,7 @@ function f4() {
|
||||
}
|
||||
|
||||
function f5() {
|
||||
>f5 : () => "" | 1
|
||||
>f5 : () => 1 | ""
|
||||
|
||||
return 1;
|
||||
>1 : 1
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
//// [literalTypeWidening.ts]
|
||||
// Widening vs. non-widening literal types
|
||||
|
||||
function f1() {
|
||||
const c1 = "hello"; // Widening type "hello"
|
||||
let v1 = c1; // Type string
|
||||
const c2 = c1; // Widening type "hello"
|
||||
let v2 = c2; // Type string
|
||||
const c3: "hello" = "hello"; // Type "hello"
|
||||
let v3 = c3; // Type "hello"
|
||||
const c4: "hello" = c1; // Type "hello"
|
||||
let v4 = c4; // Type "hello"
|
||||
}
|
||||
|
||||
function f2(cond: boolean) {
|
||||
const c1 = cond ? "foo" : "bar"; // widening "foo" | widening "bar"
|
||||
const c2: "foo" | "bar" = c1; // "foo" | "bar"
|
||||
const c3 = cond ? c1 : c2; // "foo" | "bar"
|
||||
const c4 = cond ? c3 : "baz"; // "foo" | "bar" | widening "baz"
|
||||
const c5: "foo" | "bar" | "baz" = c4; // "foo" | "bar" | "baz"
|
||||
let v1 = c1; // string
|
||||
let v2 = c2; // "foo" | "bar"
|
||||
let v3 = c3; // "foo" | "bar"
|
||||
let v4 = c4; // string
|
||||
let v5 = c5; // "foo" | "bar" | "baz"
|
||||
}
|
||||
|
||||
function f3() {
|
||||
const c1 = 123; // Widening type 123
|
||||
let v1 = c1; // Type number
|
||||
const c2 = c1; // Widening type 123
|
||||
let v2 = c2; // Type number
|
||||
const c3: 123 = 123; // Type 123
|
||||
let v3 = c3; // Type 123
|
||||
const c4: 123 = c1; // Type 123
|
||||
let v4 = c4; // Type 123
|
||||
}
|
||||
|
||||
function f4(cond: boolean) {
|
||||
const c1 = cond ? 123 : 456; // widening 123 | widening 456
|
||||
const c2: 123 | 456 = c1; // 123 | 456
|
||||
const c3 = cond ? c1 : c2; // 123 | 456
|
||||
const c4 = cond ? c3 : 789; // 123 | 456 | widening 789
|
||||
const c5: 123 | 456 | 789 = c4; // 123 | 456 | 789
|
||||
let v1 = c1; // number
|
||||
let v2 = c2; // 123 | 456
|
||||
let v3 = c3; // 123 | 456
|
||||
let v4 = c4; // number
|
||||
let v5 = c5; // 123 | 456 | 789
|
||||
}
|
||||
|
||||
function f5() {
|
||||
const c1 = "foo";
|
||||
let v1 = c1;
|
||||
const c2: "foo" = "foo";
|
||||
let v2 = c2;
|
||||
const c3 = "foo" as "foo";
|
||||
let v3 = c3;
|
||||
const c4 = <"foo">"foo";
|
||||
let v4 = c4;
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type FAILURE = "FAILURE";
|
||||
const FAILURE = "FAILURE";
|
||||
|
||||
type Result<T> = T | FAILURE;
|
||||
|
||||
function doWork<T>(): Result<T> {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
function isSuccess<T>(result: Result<T>): result is T {
|
||||
return !isFailure(result);
|
||||
}
|
||||
|
||||
function isFailure<T>(result: Result<T>): result is FAILURE {
|
||||
return result === FAILURE;
|
||||
}
|
||||
|
||||
function increment(x: number): number {
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
let result = doWork<number>();
|
||||
|
||||
if (isSuccess(result)) {
|
||||
increment(result);
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type TestEvent = "onmouseover" | "onmouseout";
|
||||
|
||||
function onMouseOver(): TestEvent { return "onmouseover"; }
|
||||
|
||||
let x = onMouseOver();
|
||||
|
||||
//// [literalTypeWidening.js]
|
||||
// Widening vs. non-widening literal types
|
||||
function f1() {
|
||||
var c1 = "hello"; // Widening type "hello"
|
||||
var v1 = c1; // Type string
|
||||
var c2 = c1; // Widening type "hello"
|
||||
var v2 = c2; // Type string
|
||||
var c3 = "hello"; // Type "hello"
|
||||
var v3 = c3; // Type "hello"
|
||||
var c4 = c1; // Type "hello"
|
||||
var v4 = c4; // Type "hello"
|
||||
}
|
||||
function f2(cond) {
|
||||
var c1 = cond ? "foo" : "bar"; // widening "foo" | widening "bar"
|
||||
var c2 = c1; // "foo" | "bar"
|
||||
var c3 = cond ? c1 : c2; // "foo" | "bar"
|
||||
var c4 = cond ? c3 : "baz"; // "foo" | "bar" | widening "baz"
|
||||
var c5 = c4; // "foo" | "bar" | "baz"
|
||||
var v1 = c1; // string
|
||||
var v2 = c2; // "foo" | "bar"
|
||||
var v3 = c3; // "foo" | "bar"
|
||||
var v4 = c4; // string
|
||||
var v5 = c5; // "foo" | "bar" | "baz"
|
||||
}
|
||||
function f3() {
|
||||
var c1 = 123; // Widening type 123
|
||||
var v1 = c1; // Type number
|
||||
var c2 = c1; // Widening type 123
|
||||
var v2 = c2; // Type number
|
||||
var c3 = 123; // Type 123
|
||||
var v3 = c3; // Type 123
|
||||
var c4 = c1; // Type 123
|
||||
var v4 = c4; // Type 123
|
||||
}
|
||||
function f4(cond) {
|
||||
var c1 = cond ? 123 : 456; // widening 123 | widening 456
|
||||
var c2 = c1; // 123 | 456
|
||||
var c3 = cond ? c1 : c2; // 123 | 456
|
||||
var c4 = cond ? c3 : 789; // 123 | 456 | widening 789
|
||||
var c5 = c4; // 123 | 456 | 789
|
||||
var v1 = c1; // number
|
||||
var v2 = c2; // 123 | 456
|
||||
var v3 = c3; // 123 | 456
|
||||
var v4 = c4; // number
|
||||
var v5 = c5; // 123 | 456 | 789
|
||||
}
|
||||
function f5() {
|
||||
var c1 = "foo";
|
||||
var v1 = c1;
|
||||
var c2 = "foo";
|
||||
var v2 = c2;
|
||||
var c3 = "foo";
|
||||
var v3 = c3;
|
||||
var c4 = "foo";
|
||||
var v4 = c4;
|
||||
}
|
||||
var FAILURE = "FAILURE";
|
||||
function doWork() {
|
||||
return FAILURE;
|
||||
}
|
||||
function isSuccess(result) {
|
||||
return !isFailure(result);
|
||||
}
|
||||
function isFailure(result) {
|
||||
return result === FAILURE;
|
||||
}
|
||||
function increment(x) {
|
||||
return x + 1;
|
||||
}
|
||||
var result = doWork();
|
||||
if (isSuccess(result)) {
|
||||
increment(result);
|
||||
}
|
||||
function onMouseOver() { return "onmouseover"; }
|
||||
var x = onMouseOver();
|
||||
@@ -0,0 +1,285 @@
|
||||
=== tests/cases/conformance/types/literal/literalTypeWidening.ts ===
|
||||
// Widening vs. non-widening literal types
|
||||
|
||||
function f1() {
|
||||
>f1 : Symbol(f1, Decl(literalTypeWidening.ts, 0, 0))
|
||||
|
||||
const c1 = "hello"; // Widening type "hello"
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 3, 9))
|
||||
|
||||
let v1 = c1; // Type string
|
||||
>v1 : Symbol(v1, Decl(literalTypeWidening.ts, 4, 7))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 3, 9))
|
||||
|
||||
const c2 = c1; // Widening type "hello"
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 5, 9))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 3, 9))
|
||||
|
||||
let v2 = c2; // Type string
|
||||
>v2 : Symbol(v2, Decl(literalTypeWidening.ts, 6, 7))
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 5, 9))
|
||||
|
||||
const c3: "hello" = "hello"; // Type "hello"
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 7, 9))
|
||||
|
||||
let v3 = c3; // Type "hello"
|
||||
>v3 : Symbol(v3, Decl(literalTypeWidening.ts, 8, 7))
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 7, 9))
|
||||
|
||||
const c4: "hello" = c1; // Type "hello"
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 9, 9))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 3, 9))
|
||||
|
||||
let v4 = c4; // Type "hello"
|
||||
>v4 : Symbol(v4, Decl(literalTypeWidening.ts, 10, 7))
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 9, 9))
|
||||
}
|
||||
|
||||
function f2(cond: boolean) {
|
||||
>f2 : Symbol(f2, Decl(literalTypeWidening.ts, 11, 1))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 13, 12))
|
||||
|
||||
const c1 = cond ? "foo" : "bar"; // widening "foo" | widening "bar"
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 14, 9))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 13, 12))
|
||||
|
||||
const c2: "foo" | "bar" = c1; // "foo" | "bar"
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 15, 9))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 14, 9))
|
||||
|
||||
const c3 = cond ? c1 : c2; // "foo" | "bar"
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 16, 9))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 13, 12))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 14, 9))
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 15, 9))
|
||||
|
||||
const c4 = cond ? c3 : "baz"; // "foo" | "bar" | widening "baz"
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 17, 9))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 13, 12))
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 16, 9))
|
||||
|
||||
const c5: "foo" | "bar" | "baz" = c4; // "foo" | "bar" | "baz"
|
||||
>c5 : Symbol(c5, Decl(literalTypeWidening.ts, 18, 9))
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 17, 9))
|
||||
|
||||
let v1 = c1; // string
|
||||
>v1 : Symbol(v1, Decl(literalTypeWidening.ts, 19, 7))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 14, 9))
|
||||
|
||||
let v2 = c2; // "foo" | "bar"
|
||||
>v2 : Symbol(v2, Decl(literalTypeWidening.ts, 20, 7))
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 15, 9))
|
||||
|
||||
let v3 = c3; // "foo" | "bar"
|
||||
>v3 : Symbol(v3, Decl(literalTypeWidening.ts, 21, 7))
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 16, 9))
|
||||
|
||||
let v4 = c4; // string
|
||||
>v4 : Symbol(v4, Decl(literalTypeWidening.ts, 22, 7))
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 17, 9))
|
||||
|
||||
let v5 = c5; // "foo" | "bar" | "baz"
|
||||
>v5 : Symbol(v5, Decl(literalTypeWidening.ts, 23, 7))
|
||||
>c5 : Symbol(c5, Decl(literalTypeWidening.ts, 18, 9))
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : Symbol(f3, Decl(literalTypeWidening.ts, 24, 1))
|
||||
|
||||
const c1 = 123; // Widening type 123
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 27, 9))
|
||||
|
||||
let v1 = c1; // Type number
|
||||
>v1 : Symbol(v1, Decl(literalTypeWidening.ts, 28, 7))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 27, 9))
|
||||
|
||||
const c2 = c1; // Widening type 123
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 29, 9))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 27, 9))
|
||||
|
||||
let v2 = c2; // Type number
|
||||
>v2 : Symbol(v2, Decl(literalTypeWidening.ts, 30, 7))
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 29, 9))
|
||||
|
||||
const c3: 123 = 123; // Type 123
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 31, 9))
|
||||
|
||||
let v3 = c3; // Type 123
|
||||
>v3 : Symbol(v3, Decl(literalTypeWidening.ts, 32, 7))
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 31, 9))
|
||||
|
||||
const c4: 123 = c1; // Type 123
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 33, 9))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 27, 9))
|
||||
|
||||
let v4 = c4; // Type 123
|
||||
>v4 : Symbol(v4, Decl(literalTypeWidening.ts, 34, 7))
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 33, 9))
|
||||
}
|
||||
|
||||
function f4(cond: boolean) {
|
||||
>f4 : Symbol(f4, Decl(literalTypeWidening.ts, 35, 1))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 37, 12))
|
||||
|
||||
const c1 = cond ? 123 : 456; // widening 123 | widening 456
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 38, 9))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 37, 12))
|
||||
|
||||
const c2: 123 | 456 = c1; // 123 | 456
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 39, 9))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 38, 9))
|
||||
|
||||
const c3 = cond ? c1 : c2; // 123 | 456
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 40, 9))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 37, 12))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 38, 9))
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 39, 9))
|
||||
|
||||
const c4 = cond ? c3 : 789; // 123 | 456 | widening 789
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 41, 9))
|
||||
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 37, 12))
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 40, 9))
|
||||
|
||||
const c5: 123 | 456 | 789 = c4; // 123 | 456 | 789
|
||||
>c5 : Symbol(c5, Decl(literalTypeWidening.ts, 42, 9))
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 41, 9))
|
||||
|
||||
let v1 = c1; // number
|
||||
>v1 : Symbol(v1, Decl(literalTypeWidening.ts, 43, 7))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 38, 9))
|
||||
|
||||
let v2 = c2; // 123 | 456
|
||||
>v2 : Symbol(v2, Decl(literalTypeWidening.ts, 44, 7))
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 39, 9))
|
||||
|
||||
let v3 = c3; // 123 | 456
|
||||
>v3 : Symbol(v3, Decl(literalTypeWidening.ts, 45, 7))
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 40, 9))
|
||||
|
||||
let v4 = c4; // number
|
||||
>v4 : Symbol(v4, Decl(literalTypeWidening.ts, 46, 7))
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 41, 9))
|
||||
|
||||
let v5 = c5; // 123 | 456 | 789
|
||||
>v5 : Symbol(v5, Decl(literalTypeWidening.ts, 47, 7))
|
||||
>c5 : Symbol(c5, Decl(literalTypeWidening.ts, 42, 9))
|
||||
}
|
||||
|
||||
function f5() {
|
||||
>f5 : Symbol(f5, Decl(literalTypeWidening.ts, 48, 1))
|
||||
|
||||
const c1 = "foo";
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 51, 9))
|
||||
|
||||
let v1 = c1;
|
||||
>v1 : Symbol(v1, Decl(literalTypeWidening.ts, 52, 7))
|
||||
>c1 : Symbol(c1, Decl(literalTypeWidening.ts, 51, 9))
|
||||
|
||||
const c2: "foo" = "foo";
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 53, 9))
|
||||
|
||||
let v2 = c2;
|
||||
>v2 : Symbol(v2, Decl(literalTypeWidening.ts, 54, 7))
|
||||
>c2 : Symbol(c2, Decl(literalTypeWidening.ts, 53, 9))
|
||||
|
||||
const c3 = "foo" as "foo";
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 55, 9))
|
||||
|
||||
let v3 = c3;
|
||||
>v3 : Symbol(v3, Decl(literalTypeWidening.ts, 56, 7))
|
||||
>c3 : Symbol(c3, Decl(literalTypeWidening.ts, 55, 9))
|
||||
|
||||
const c4 = <"foo">"foo";
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 57, 9))
|
||||
|
||||
let v4 = c4;
|
||||
>v4 : Symbol(v4, Decl(literalTypeWidening.ts, 58, 7))
|
||||
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 57, 9))
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type FAILURE = "FAILURE";
|
||||
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
|
||||
|
||||
const FAILURE = "FAILURE";
|
||||
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
|
||||
|
||||
type Result<T> = T | FAILURE;
|
||||
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 66, 12))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 66, 12))
|
||||
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
|
||||
|
||||
function doWork<T>(): Result<T> {
|
||||
>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 66, 29))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 68, 16))
|
||||
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 68, 16))
|
||||
|
||||
return FAILURE;
|
||||
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
|
||||
}
|
||||
|
||||
function isSuccess<T>(result: Result<T>): result is T {
|
||||
>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 70, 1))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19))
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22))
|
||||
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19))
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19))
|
||||
|
||||
return !isFailure(result);
|
||||
>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 74, 1))
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22))
|
||||
}
|
||||
|
||||
function isFailure<T>(result: Result<T>): result is FAILURE {
|
||||
>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 74, 1))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 76, 19))
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22))
|
||||
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
|
||||
>T : Symbol(T, Decl(literalTypeWidening.ts, 76, 19))
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22))
|
||||
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
|
||||
|
||||
return result === FAILURE;
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22))
|
||||
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
|
||||
}
|
||||
|
||||
function increment(x: number): number {
|
||||
>increment : Symbol(increment, Decl(literalTypeWidening.ts, 78, 1))
|
||||
>x : Symbol(x, Decl(literalTypeWidening.ts, 80, 19))
|
||||
|
||||
return x + 1;
|
||||
>x : Symbol(x, Decl(literalTypeWidening.ts, 80, 19))
|
||||
}
|
||||
|
||||
let result = doWork<number>();
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3))
|
||||
>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 66, 29))
|
||||
|
||||
if (isSuccess(result)) {
|
||||
>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 70, 1))
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3))
|
||||
|
||||
increment(result);
|
||||
>increment : Symbol(increment, Decl(literalTypeWidening.ts, 78, 1))
|
||||
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3))
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type TestEvent = "onmouseover" | "onmouseout";
|
||||
>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 88, 1))
|
||||
|
||||
function onMouseOver(): TestEvent { return "onmouseover"; }
|
||||
>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 92, 46))
|
||||
>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 88, 1))
|
||||
|
||||
let x = onMouseOver();
|
||||
>x : Symbol(x, Decl(literalTypeWidening.ts, 96, 3))
|
||||
>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 92, 46))
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
=== tests/cases/conformance/types/literal/literalTypeWidening.ts ===
|
||||
// Widening vs. non-widening literal types
|
||||
|
||||
function f1() {
|
||||
>f1 : () => void
|
||||
|
||||
const c1 = "hello"; // Widening type "hello"
|
||||
>c1 : "hello"
|
||||
>"hello" : "hello"
|
||||
|
||||
let v1 = c1; // Type string
|
||||
>v1 : string
|
||||
>c1 : "hello"
|
||||
|
||||
const c2 = c1; // Widening type "hello"
|
||||
>c2 : "hello"
|
||||
>c1 : "hello"
|
||||
|
||||
let v2 = c2; // Type string
|
||||
>v2 : string
|
||||
>c2 : "hello"
|
||||
|
||||
const c3: "hello" = "hello"; // Type "hello"
|
||||
>c3 : "hello"
|
||||
>"hello" : "hello"
|
||||
|
||||
let v3 = c3; // Type "hello"
|
||||
>v3 : "hello"
|
||||
>c3 : "hello"
|
||||
|
||||
const c4: "hello" = c1; // Type "hello"
|
||||
>c4 : "hello"
|
||||
>c1 : "hello"
|
||||
|
||||
let v4 = c4; // Type "hello"
|
||||
>v4 : "hello"
|
||||
>c4 : "hello"
|
||||
}
|
||||
|
||||
function f2(cond: boolean) {
|
||||
>f2 : (cond: boolean) => void
|
||||
>cond : boolean
|
||||
|
||||
const c1 = cond ? "foo" : "bar"; // widening "foo" | widening "bar"
|
||||
>c1 : "foo" | "bar"
|
||||
>cond ? "foo" : "bar" : "foo" | "bar"
|
||||
>cond : boolean
|
||||
>"foo" : "foo"
|
||||
>"bar" : "bar"
|
||||
|
||||
const c2: "foo" | "bar" = c1; // "foo" | "bar"
|
||||
>c2 : "foo" | "bar"
|
||||
>c1 : "foo" | "bar"
|
||||
|
||||
const c3 = cond ? c1 : c2; // "foo" | "bar"
|
||||
>c3 : "foo" | "bar"
|
||||
>cond ? c1 : c2 : "foo" | "bar"
|
||||
>cond : boolean
|
||||
>c1 : "foo" | "bar"
|
||||
>c2 : "foo" | "bar"
|
||||
|
||||
const c4 = cond ? c3 : "baz"; // "foo" | "bar" | widening "baz"
|
||||
>c4 : "foo" | "bar" | "baz"
|
||||
>cond ? c3 : "baz" : "foo" | "bar" | "baz"
|
||||
>cond : boolean
|
||||
>c3 : "foo" | "bar"
|
||||
>"baz" : "baz"
|
||||
|
||||
const c5: "foo" | "bar" | "baz" = c4; // "foo" | "bar" | "baz"
|
||||
>c5 : "foo" | "bar" | "baz"
|
||||
>c4 : "foo" | "bar" | "baz"
|
||||
|
||||
let v1 = c1; // string
|
||||
>v1 : string
|
||||
>c1 : "foo" | "bar"
|
||||
|
||||
let v2 = c2; // "foo" | "bar"
|
||||
>v2 : "foo" | "bar"
|
||||
>c2 : "foo" | "bar"
|
||||
|
||||
let v3 = c3; // "foo" | "bar"
|
||||
>v3 : "foo" | "bar"
|
||||
>c3 : "foo" | "bar"
|
||||
|
||||
let v4 = c4; // string
|
||||
>v4 : string
|
||||
>c4 : "foo" | "bar" | "baz"
|
||||
|
||||
let v5 = c5; // "foo" | "bar" | "baz"
|
||||
>v5 : "foo" | "bar" | "baz"
|
||||
>c5 : "foo" | "bar" | "baz"
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : () => void
|
||||
|
||||
const c1 = 123; // Widening type 123
|
||||
>c1 : 123
|
||||
>123 : 123
|
||||
|
||||
let v1 = c1; // Type number
|
||||
>v1 : number
|
||||
>c1 : 123
|
||||
|
||||
const c2 = c1; // Widening type 123
|
||||
>c2 : 123
|
||||
>c1 : 123
|
||||
|
||||
let v2 = c2; // Type number
|
||||
>v2 : number
|
||||
>c2 : 123
|
||||
|
||||
const c3: 123 = 123; // Type 123
|
||||
>c3 : 123
|
||||
>123 : 123
|
||||
|
||||
let v3 = c3; // Type 123
|
||||
>v3 : 123
|
||||
>c3 : 123
|
||||
|
||||
const c4: 123 = c1; // Type 123
|
||||
>c4 : 123
|
||||
>c1 : 123
|
||||
|
||||
let v4 = c4; // Type 123
|
||||
>v4 : 123
|
||||
>c4 : 123
|
||||
}
|
||||
|
||||
function f4(cond: boolean) {
|
||||
>f4 : (cond: boolean) => void
|
||||
>cond : boolean
|
||||
|
||||
const c1 = cond ? 123 : 456; // widening 123 | widening 456
|
||||
>c1 : 123 | 456
|
||||
>cond ? 123 : 456 : 123 | 456
|
||||
>cond : boolean
|
||||
>123 : 123
|
||||
>456 : 456
|
||||
|
||||
const c2: 123 | 456 = c1; // 123 | 456
|
||||
>c2 : 123 | 456
|
||||
>c1 : 123 | 456
|
||||
|
||||
const c3 = cond ? c1 : c2; // 123 | 456
|
||||
>c3 : 123 | 456
|
||||
>cond ? c1 : c2 : 123 | 456
|
||||
>cond : boolean
|
||||
>c1 : 123 | 456
|
||||
>c2 : 123 | 456
|
||||
|
||||
const c4 = cond ? c3 : 789; // 123 | 456 | widening 789
|
||||
>c4 : 123 | 456 | 789
|
||||
>cond ? c3 : 789 : 123 | 456 | 789
|
||||
>cond : boolean
|
||||
>c3 : 123 | 456
|
||||
>789 : 789
|
||||
|
||||
const c5: 123 | 456 | 789 = c4; // 123 | 456 | 789
|
||||
>c5 : 123 | 456 | 789
|
||||
>c4 : 123 | 456 | 789
|
||||
|
||||
let v1 = c1; // number
|
||||
>v1 : number
|
||||
>c1 : 123 | 456
|
||||
|
||||
let v2 = c2; // 123 | 456
|
||||
>v2 : 123 | 456
|
||||
>c2 : 123 | 456
|
||||
|
||||
let v3 = c3; // 123 | 456
|
||||
>v3 : 123 | 456
|
||||
>c3 : 123 | 456
|
||||
|
||||
let v4 = c4; // number
|
||||
>v4 : number
|
||||
>c4 : 123 | 456 | 789
|
||||
|
||||
let v5 = c5; // 123 | 456 | 789
|
||||
>v5 : 123 | 456 | 789
|
||||
>c5 : 123 | 456 | 789
|
||||
}
|
||||
|
||||
function f5() {
|
||||
>f5 : () => void
|
||||
|
||||
const c1 = "foo";
|
||||
>c1 : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
let v1 = c1;
|
||||
>v1 : string
|
||||
>c1 : "foo"
|
||||
|
||||
const c2: "foo" = "foo";
|
||||
>c2 : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
let v2 = c2;
|
||||
>v2 : "foo"
|
||||
>c2 : "foo"
|
||||
|
||||
const c3 = "foo" as "foo";
|
||||
>c3 : "foo"
|
||||
>"foo" as "foo" : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
let v3 = c3;
|
||||
>v3 : "foo"
|
||||
>c3 : "foo"
|
||||
|
||||
const c4 = <"foo">"foo";
|
||||
>c4 : "foo"
|
||||
><"foo">"foo" : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
let v4 = c4;
|
||||
>v4 : "foo"
|
||||
>c4 : "foo"
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type FAILURE = "FAILURE";
|
||||
>FAILURE : "FAILURE"
|
||||
|
||||
const FAILURE = "FAILURE";
|
||||
>FAILURE : "FAILURE"
|
||||
>"FAILURE" : "FAILURE"
|
||||
|
||||
type Result<T> = T | FAILURE;
|
||||
>Result : Result<T>
|
||||
>T : T
|
||||
>T : T
|
||||
>FAILURE : "FAILURE"
|
||||
|
||||
function doWork<T>(): Result<T> {
|
||||
>doWork : <T>() => Result<T>
|
||||
>T : T
|
||||
>Result : Result<T>
|
||||
>T : T
|
||||
|
||||
return FAILURE;
|
||||
>FAILURE : "FAILURE"
|
||||
}
|
||||
|
||||
function isSuccess<T>(result: Result<T>): result is T {
|
||||
>isSuccess : <T>(result: Result<T>) => result is T
|
||||
>T : T
|
||||
>result : Result<T>
|
||||
>Result : Result<T>
|
||||
>T : T
|
||||
>result : any
|
||||
>T : T
|
||||
|
||||
return !isFailure(result);
|
||||
>!isFailure(result) : boolean
|
||||
>isFailure(result) : boolean
|
||||
>isFailure : <T>(result: Result<T>) => result is "FAILURE"
|
||||
>result : Result<T>
|
||||
}
|
||||
|
||||
function isFailure<T>(result: Result<T>): result is FAILURE {
|
||||
>isFailure : <T>(result: Result<T>) => result is "FAILURE"
|
||||
>T : T
|
||||
>result : Result<T>
|
||||
>Result : Result<T>
|
||||
>T : T
|
||||
>result : any
|
||||
>FAILURE : "FAILURE"
|
||||
|
||||
return result === FAILURE;
|
||||
>result === FAILURE : boolean
|
||||
>result : Result<T>
|
||||
>FAILURE : "FAILURE"
|
||||
}
|
||||
|
||||
function increment(x: number): number {
|
||||
>increment : (x: number) => number
|
||||
>x : number
|
||||
|
||||
return x + 1;
|
||||
>x + 1 : number
|
||||
>x : number
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
let result = doWork<number>();
|
||||
>result : Result<number>
|
||||
>doWork<number>() : Result<number>
|
||||
>doWork : <T>() => Result<T>
|
||||
|
||||
if (isSuccess(result)) {
|
||||
>isSuccess(result) : boolean
|
||||
>isSuccess : <T>(result: Result<T>) => result is T
|
||||
>result : Result<number>
|
||||
|
||||
increment(result);
|
||||
>increment(result) : number
|
||||
>increment : (x: number) => number
|
||||
>result : number
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type TestEvent = "onmouseover" | "onmouseout";
|
||||
>TestEvent : TestEvent
|
||||
|
||||
function onMouseOver(): TestEvent { return "onmouseover"; }
|
||||
>onMouseOver : () => TestEvent
|
||||
>TestEvent : TestEvent
|
||||
>"onmouseover" : "onmouseover"
|
||||
|
||||
let x = onMouseOver();
|
||||
>x : TestEvent
|
||||
>onMouseOver() : TestEvent
|
||||
>onMouseOver : () => TestEvent
|
||||
|
||||
@@ -482,7 +482,7 @@ function f6() {
|
||||
const { c1 = true, c2 = 0, c3 = "foo" } = { c1: false, c2: 1, c3: "bar" };
|
||||
>c1 : boolean
|
||||
>true : true
|
||||
>c2 : 0 | 1
|
||||
>c2 : 1 | 0
|
||||
>0 : 0
|
||||
>c3 : "foo" | "bar"
|
||||
>"foo" : "foo"
|
||||
@@ -552,10 +552,10 @@ class C2 {
|
||||
>0 : 0
|
||||
}
|
||||
bar() {
|
||||
>bar : () => 0 | 1
|
||||
>bar : () => 1 | 0
|
||||
|
||||
return cond ? 0 : 1;
|
||||
>cond ? 0 : 1 : 0 | 1
|
||||
>cond ? 0 : 1 : 1 | 0
|
||||
>cond : boolean
|
||||
>0 : 0
|
||||
>1 : 1
|
||||
|
||||
@@ -370,7 +370,7 @@ function f14(x: 0 | 1 | 2, y: string) {
|
||||
>y : string
|
||||
|
||||
var b = x || y;
|
||||
>b : string | number
|
||||
>b : string | 1 | 2
|
||||
>x || y : string | 1 | 2
|
||||
>x : 0 | 1 | 2
|
||||
>y : string
|
||||
@@ -383,25 +383,25 @@ function f15(x: 0 | false, y: 1 | "one") {
|
||||
>y : 1 | "one"
|
||||
|
||||
var a = x && y;
|
||||
>a : number | boolean
|
||||
>a : boolean | 0
|
||||
>x && y : false | 0
|
||||
>x : false | 0
|
||||
>y : 1 | "one"
|
||||
|
||||
var b = y && x;
|
||||
>b : number | boolean
|
||||
>b : boolean | 0
|
||||
>y && x : false | 0
|
||||
>y : 1 | "one"
|
||||
>x : false | 0
|
||||
|
||||
var c = x || y;
|
||||
>c : string | number
|
||||
>c : 1 | "one"
|
||||
>x || y : 1 | "one"
|
||||
>x : false | 0
|
||||
>y : 1 | "one"
|
||||
|
||||
var d = y || x;
|
||||
>d : string | number | boolean
|
||||
>d : boolean | 0 | 1 | "one"
|
||||
>y || x : false | 0 | 1 | "one"
|
||||
>y : 1 | "one"
|
||||
>x : false | 0
|
||||
|
||||
@@ -365,13 +365,13 @@ function f14(x: 0 | 1 | 2, y: string) {
|
||||
>y : string
|
||||
|
||||
var a = x && y;
|
||||
>a : string | number
|
||||
>a : string | 0
|
||||
>x && y : string | 0
|
||||
>x : 0 | 1 | 2
|
||||
>y : string
|
||||
|
||||
var b = x || y;
|
||||
>b : string | number
|
||||
>b : string | 1 | 2
|
||||
>x || y : string | 1 | 2
|
||||
>x : 0 | 1 | 2
|
||||
>y : string
|
||||
@@ -384,25 +384,25 @@ function f15(x: 0 | false, y: 1 | "one") {
|
||||
>y : 1 | "one"
|
||||
|
||||
var a = x && y;
|
||||
>a : number | boolean
|
||||
>a : boolean | 0
|
||||
>x && y : false | 0
|
||||
>x : false | 0
|
||||
>y : 1 | "one"
|
||||
|
||||
var b = y && x;
|
||||
>b : number | boolean
|
||||
>b : boolean | 0
|
||||
>y && x : false | 0
|
||||
>y : 1 | "one"
|
||||
>x : false | 0
|
||||
|
||||
var c = x || y;
|
||||
>c : string | number
|
||||
>c : 1 | "one"
|
||||
>x || y : 1 | "one"
|
||||
>x : false | 0
|
||||
>y : 1 | "one"
|
||||
|
||||
var d = y || x;
|
||||
>d : string | number
|
||||
>d : 1 | "one"
|
||||
>y || x : 1 | "one"
|
||||
>y : 1 | "one"
|
||||
>x : false | 0
|
||||
|
||||
@@ -17,5 +17,5 @@ exports.foo = foo;
|
||||
|
||||
|
||||
//// [shorthandOfExportedEntity01_targetES2015_CommonJS.d.ts]
|
||||
export declare const test: "test";
|
||||
export declare const test = "test";
|
||||
export declare function foo(): void;
|
||||
|
||||
@@ -17,5 +17,5 @@ exports.foo = foo;
|
||||
|
||||
|
||||
//// [shorthandOfExportedEntity02_targetES5_CommonJS.d.ts]
|
||||
export declare const test: "test";
|
||||
export declare const test = "test";
|
||||
export declare function foo(): void;
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
tests/cases/conformance/types/stringLiteral/stringLiteralTypesAndLogicalOrExpressions01.ts(6,5): error TS2322: Type 'string' is not assignable to type '"foo"'.
|
||||
tests/cases/conformance/types/stringLiteral/stringLiteralTypesAndLogicalOrExpressions01.ts(8,5): error TS2322: Type 'string' is not assignable to type '"foo" | "bar"'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAndLogicalOrExpressions01.ts (2 errors) ====
|
||||
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAndLogicalOrExpressions01.ts (1 errors) ====
|
||||
|
||||
declare function myRandBool(): boolean;
|
||||
|
||||
let a: "foo" = "foo";
|
||||
let b = a || "foo";
|
||||
let c: "foo" = b;
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"foo"'.
|
||||
let d = b || "bar";
|
||||
let e: "foo" | "bar" = d;
|
||||
~
|
||||
|
||||
@@ -20,7 +20,7 @@ var e = d;
|
||||
//// [stringLiteralTypesAndLogicalOrExpressions01.d.ts]
|
||||
declare function myRandBool(): boolean;
|
||||
declare let a: "foo";
|
||||
declare let b: string;
|
||||
declare let b: "foo";
|
||||
declare let c: "foo";
|
||||
declare let d: string;
|
||||
declare let e: "foo" | "bar";
|
||||
|
||||
@@ -38,8 +38,8 @@ hResult = h("bar");
|
||||
declare function foo<T extends "foo">(f: (x: T) => T): (x: T) => T;
|
||||
declare function bar<T extends "foo" | "bar">(f: (x: T) => T): (x: T) => T;
|
||||
declare let f: (x: "foo") => "foo";
|
||||
declare let fResult: string;
|
||||
declare let fResult: "foo";
|
||||
declare let g: (x: "foo") => "foo";
|
||||
declare let gResult: string;
|
||||
declare let gResult: "foo";
|
||||
declare let h: (x: "foo" | "bar") => "foo" | "bar";
|
||||
declare let hResult: string;
|
||||
declare let hResult: "foo" | "bar";
|
||||
|
||||
@@ -33,7 +33,7 @@ let f = foo(x => x);
|
||||
>x : "foo"
|
||||
|
||||
let fResult = f("foo");
|
||||
>fResult : string
|
||||
>fResult : "foo"
|
||||
>f("foo") : "foo"
|
||||
>f : (x: "foo") => "foo"
|
||||
>"foo" : "foo"
|
||||
@@ -48,7 +48,7 @@ let g = foo((x => x));
|
||||
>x : "foo"
|
||||
|
||||
let gResult = g("foo");
|
||||
>gResult : string
|
||||
>gResult : "foo"
|
||||
>g("foo") : "foo"
|
||||
>g : (x: "foo") => "foo"
|
||||
>"foo" : "foo"
|
||||
@@ -62,14 +62,14 @@ let h = bar(x => x);
|
||||
>x : "foo" | "bar"
|
||||
|
||||
let hResult = h("foo");
|
||||
>hResult : string
|
||||
>hResult : "foo" | "bar"
|
||||
>h("foo") : "foo" | "bar"
|
||||
>h : (x: "foo" | "bar") => "foo" | "bar"
|
||||
>"foo" : "foo"
|
||||
|
||||
hResult = h("bar");
|
||||
>hResult = h("bar") : "foo" | "bar"
|
||||
>hResult : string
|
||||
>hResult : "foo" | "bar"
|
||||
>h("bar") : "foo" | "bar"
|
||||
>h : (x: "foo" | "bar") => "foo" | "bar"
|
||||
>"bar" : "bar"
|
||||
|
||||
@@ -18,4 +18,4 @@ var fResult = f("foo");
|
||||
//// [stringLiteralTypesAsTypeParameterConstraint02.d.ts]
|
||||
declare function foo<T extends "foo">(f: (x: T) => T): (x: T) => T;
|
||||
declare let f: (x: "foo") => "foo";
|
||||
declare let fResult: string;
|
||||
declare let fResult: "foo";
|
||||
|
||||
@@ -26,7 +26,7 @@ let f = foo((y: "foo" | "bar") => y === "foo" ? y : "foo");
|
||||
>"foo" : "foo"
|
||||
|
||||
let fResult = f("foo");
|
||||
>fResult : string
|
||||
>fResult : "foo"
|
||||
>f("foo") : "foo"
|
||||
>f : (x: "foo") => "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes01.ts(16,9): error TS2322: Type 'string' is not assignable to type '"foo" | "bar" | "baz"'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes01.ts (1 errors) ====
|
||||
|
||||
type T = "foo" | "bar" | "baz";
|
||||
|
||||
var x: "foo" | "bar" | "baz" = undefined;
|
||||
var y: T = undefined;
|
||||
|
||||
if (x === "foo") {
|
||||
let a = x;
|
||||
}
|
||||
else if (x !== "bar") {
|
||||
let b = x || y;
|
||||
}
|
||||
else {
|
||||
let c = x;
|
||||
let d = y;
|
||||
let e: (typeof x) | (typeof y) = c || d;
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"foo" | "bar" | "baz"'.
|
||||
}
|
||||
|
||||
x = y;
|
||||
y = x;
|
||||
@@ -1,62 +1,62 @@
|
||||
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes02.ts ===
|
||||
|
||||
type T = string | "foo" | "bar" | "baz";
|
||||
>T : string | "foo" | "bar" | "baz"
|
||||
>T : string
|
||||
|
||||
var x: "foo" | "bar" | "baz" | string = undefined;
|
||||
>x : string | "foo" | "bar" | "baz"
|
||||
>x : string
|
||||
>undefined : undefined
|
||||
|
||||
var y: T = undefined;
|
||||
>y : string | "foo" | "bar" | "baz"
|
||||
>T : string | "foo" | "bar" | "baz"
|
||||
>y : string
|
||||
>T : string
|
||||
>undefined : undefined
|
||||
|
||||
if (x === "foo") {
|
||||
>x === "foo" : boolean
|
||||
>x : string | "foo" | "bar" | "baz"
|
||||
>x : string
|
||||
>"foo" : "foo"
|
||||
|
||||
let a = x;
|
||||
>a : string
|
||||
>x : string | "foo"
|
||||
>x : string
|
||||
}
|
||||
else if (x !== "bar") {
|
||||
>x !== "bar" : boolean
|
||||
>x : string | "bar" | "baz"
|
||||
>x : string
|
||||
>"bar" : "bar"
|
||||
|
||||
let b = x || y;
|
||||
>b : string
|
||||
>x || y : string
|
||||
>x : string | "baz"
|
||||
>y : string | "foo" | "bar" | "baz"
|
||||
>x : string
|
||||
>y : string
|
||||
}
|
||||
else {
|
||||
let c = x;
|
||||
>c : string
|
||||
>x : string | "bar"
|
||||
>x : string
|
||||
|
||||
let d = y;
|
||||
>d : string
|
||||
>y : string | "foo" | "bar" | "baz"
|
||||
>y : string
|
||||
|
||||
let e: (typeof x) | (typeof y) = c || d;
|
||||
>e : string | "foo" | "bar" | "baz"
|
||||
>x : string | "bar"
|
||||
>y : string | "foo" | "bar" | "baz"
|
||||
>e : string
|
||||
>x : string
|
||||
>y : string
|
||||
>c || d : string
|
||||
>c : string
|
||||
>d : string
|
||||
}
|
||||
|
||||
x = y;
|
||||
>x = y : string | "foo" | "bar" | "baz"
|
||||
>x : string | "foo" | "bar" | "baz"
|
||||
>y : string | "foo" | "bar" | "baz"
|
||||
>x = y : string
|
||||
>x : string
|
||||
>y : string
|
||||
|
||||
y = x;
|
||||
>y = x : string | "foo" | "bar" | "baz"
|
||||
>y : string | "foo" | "bar" | "baz"
|
||||
>x : string | "foo" | "bar" | "baz"
|
||||
>y = x : string
|
||||
>y : string
|
||||
>x : string
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes03.ts(16,9): error TS2322: Type 'string | number' is not assignable to type 'number | "foo" | "bar"'.
|
||||
Type 'string' is not assignable to type 'number | "foo" | "bar"'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes03.ts (1 errors) ====
|
||||
|
||||
type T = number | "foo" | "bar";
|
||||
|
||||
var x: "foo" | "bar" | number;
|
||||
var y: T = undefined;
|
||||
|
||||
if (x === "foo") {
|
||||
let a = x;
|
||||
}
|
||||
else if (x !== "bar") {
|
||||
let b = x || y;
|
||||
}
|
||||
else {
|
||||
let c = x;
|
||||
let d = y;
|
||||
let e: (typeof x) | (typeof y) = c || d;
|
||||
~
|
||||
!!! error TS2322: Type 'string | number' is not assignable to type 'number | "foo" | "bar"'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number | "foo" | "bar"'.
|
||||
}
|
||||
|
||||
x = y;
|
||||
y = x;
|
||||
@@ -19,7 +19,7 @@ if (x === "") {
|
||||
>"" : ""
|
||||
|
||||
let a = x;
|
||||
>a : string
|
||||
>a : ""
|
||||
>x : ""
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ if (x !== "") {
|
||||
>"" : ""
|
||||
|
||||
let b = x;
|
||||
>b : string
|
||||
>b : "foo"
|
||||
>x : "foo"
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ if (x == "") {
|
||||
>"" : ""
|
||||
|
||||
let c = x;
|
||||
>c : string
|
||||
>c : ""
|
||||
>x : ""
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ if (x != "") {
|
||||
>"" : ""
|
||||
|
||||
let d = x;
|
||||
>d : string
|
||||
>d : "foo"
|
||||
>x : "foo"
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ if (x) {
|
||||
>x : T
|
||||
|
||||
let e = x;
|
||||
>e : string
|
||||
>e : "foo"
|
||||
>x : "foo"
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ if (!x) {
|
||||
>x : T
|
||||
|
||||
let f = x;
|
||||
>f : string
|
||||
>f : T
|
||||
>x : T
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ if (!!x) {
|
||||
>x : T
|
||||
|
||||
let g = x;
|
||||
>g : string
|
||||
>g : "foo"
|
||||
>x : "foo"
|
||||
}
|
||||
|
||||
@@ -87,6 +87,6 @@ if (!!!x) {
|
||||
>x : T
|
||||
|
||||
let h = x;
|
||||
>h : string
|
||||
>h : T
|
||||
>x : T
|
||||
}
|
||||
|
||||
@@ -100,12 +100,12 @@ declare function getFalsyPrimitive(x: "number" | "string"): number | string;
|
||||
declare function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean;
|
||||
declare namespace Consts1 {
|
||||
}
|
||||
declare const string: "string";
|
||||
declare const number: "number";
|
||||
declare const boolean: "boolean";
|
||||
declare const stringOrNumber: "string" | "number";
|
||||
declare const stringOrBoolean: "string" | "boolean";
|
||||
declare const booleanOrNumber: "number" | "boolean";
|
||||
declare const stringOrBooleanOrNumber: "string" | "number" | "boolean";
|
||||
declare const string = "string";
|
||||
declare const number = "number";
|
||||
declare const boolean = "boolean";
|
||||
declare const stringOrNumber: string;
|
||||
declare const stringOrBoolean: string;
|
||||
declare const booleanOrNumber: string;
|
||||
declare const stringOrBooleanOrNumber: string;
|
||||
declare namespace Consts2 {
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ if (kindIs(x, "A")) {
|
||||
>"A" : "A"
|
||||
|
||||
let a = x;
|
||||
>a : string
|
||||
>a : "A"
|
||||
>x : "A"
|
||||
}
|
||||
else {
|
||||
let b = x;
|
||||
>b : string
|
||||
>b : "B"
|
||||
>x : "B"
|
||||
}
|
||||
|
||||
@@ -59,11 +59,11 @@ if (!kindIs(x, "B")) {
|
||||
>"B" : "B"
|
||||
|
||||
let c = x;
|
||||
>c : string
|
||||
>c : "A"
|
||||
>x : "A"
|
||||
}
|
||||
else {
|
||||
let d = x;
|
||||
>d : string
|
||||
>d : "B"
|
||||
>x : "B"
|
||||
}
|
||||
|
||||
@@ -259,14 +259,14 @@ function f6<T extends String>(x: T) {
|
||||
|
||||
var r2 = true ? '' : x; // ok
|
||||
>r2 : string | T
|
||||
>true ? '' : x : "" | T
|
||||
>true ? '' : x : T | ""
|
||||
>true : true
|
||||
>'' : ""
|
||||
>x : T
|
||||
|
||||
var r2 = true ? x : ''; // ok
|
||||
>r2 : string | T
|
||||
>true ? x : '' : "" | T
|
||||
>true ? x : '' : T | ""
|
||||
>true : true
|
||||
>x : T
|
||||
>'' : ""
|
||||
|
||||
@@ -11,17 +11,21 @@ tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes0
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(55,43): error TS2345: Argument of type '"World"' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(57,52): error TS2345: Argument of type '"World"' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(58,43): error TS2345: Argument of type '"World"' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(68,25): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(70,25): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(75,30): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(77,30): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(61,5): error TS2322: Type 'string' is not assignable to type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(63,5): error TS2322: Type 'string' is not assignable to type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(75,5): error TS2322: Type '"Hello" | "World"' is not assignable to type '"Hello"'.
|
||||
Type '"World"' is not assignable to type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(77,5): error TS2322: Type '"Hello" | "World"' is not assignable to type '"Hello"'.
|
||||
Type '"World"' is not assignable to type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(87,43): error TS2345: Argument of type '"World"' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(88,43): error TS2345: Argument of type '"Hello"' is not assignable to parameter of type '"World"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(89,52): error TS2345: Argument of type '"World"' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(100,25): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(104,25): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(107,30): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(111,30): error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(93,5): error TS2322: Type 'string' is not assignable to type '"Hello" | "World"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(97,5): error TS2322: Type 'string' is not assignable to type '"Hello" | "World"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(100,25): error TS2345: Argument of type '"Hello" | "World"' is not assignable to parameter of type '"Hello"'.
|
||||
Type '"World"' is not assignable to type '"Hello"'.
|
||||
tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts(104,25): error TS2345: Argument of type '"Hello" | "World"' is not assignable to parameter of type '"Hello"'.
|
||||
Type '"World"' is not assignable to type '"Hello"'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes01.ts (24 errors) ====
|
||||
@@ -112,30 +116,32 @@ tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes0
|
||||
|
||||
// Assignment from the returned value should cause an error.
|
||||
a = takeReturnString(a);
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"Hello"'.
|
||||
b = takeReturnString(b);
|
||||
c = takeReturnString(c);
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"Hello"'.
|
||||
d = takeReturnString(d);
|
||||
e = takeReturnString(e);
|
||||
|
||||
// Should be valid
|
||||
a = takeReturnHello(a);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
b = takeReturnHello(b);
|
||||
c = takeReturnHello(c);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
d = takeReturnHello(d);
|
||||
e = takeReturnHello(e);
|
||||
|
||||
// Assignment from the returned value should cause an error.
|
||||
a = takeReturnHelloWorld(a);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
~
|
||||
!!! error TS2322: Type '"Hello" | "World"' is not assignable to type '"Hello"'.
|
||||
!!! error TS2322: Type '"World"' is not assignable to type '"Hello"'.
|
||||
b = takeReturnHelloWorld(b);
|
||||
c = takeReturnHelloWorld(c);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
~
|
||||
!!! error TS2322: Type '"Hello" | "World"' is not assignable to type '"Hello"'.
|
||||
!!! error TS2322: Type '"World"' is not assignable to type '"Hello"'.
|
||||
d = takeReturnHelloWorld(d);
|
||||
e = takeReturnHelloWorld(e);
|
||||
}
|
||||
@@ -158,30 +164,32 @@ tests/cases/conformance/types/stringLiteral/typeArgumentsWithStringLiteralTypes0
|
||||
|
||||
// Assignment from the returned value should cause an error.
|
||||
a = takeReturnString(a);
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"Hello" | "World"'.
|
||||
b = takeReturnString(b);
|
||||
c = takeReturnString(c);
|
||||
d = takeReturnString(d);
|
||||
e = takeReturnString(e);
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"Hello" | "World"'.
|
||||
|
||||
// Passing these as arguments should cause an error.
|
||||
a = takeReturnHello(a);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
!!! error TS2345: Argument of type '"Hello" | "World"' is not assignable to parameter of type '"Hello"'.
|
||||
!!! error TS2345: Type '"World"' is not assignable to type '"Hello"'.
|
||||
b = takeReturnHello(b);
|
||||
c = takeReturnHello(c);
|
||||
d = takeReturnHello(d);
|
||||
e = takeReturnHello(e);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello"'.
|
||||
!!! error TS2345: Argument of type '"Hello" | "World"' is not assignable to parameter of type '"Hello"'.
|
||||
!!! error TS2345: Type '"World"' is not assignable to type '"Hello"'.
|
||||
|
||||
// Both should be valid.
|
||||
a = takeReturnHelloWorld(a);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
b = takeReturnHelloWorld(b);
|
||||
c = takeReturnHelloWorld(c);
|
||||
d = takeReturnHelloWorld(d);
|
||||
e = takeReturnHelloWorld(e);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"Hello" | "World"'.
|
||||
}
|
||||
@@ -229,16 +229,16 @@ declare namespace n1 {
|
||||
let e: string;
|
||||
}
|
||||
declare namespace n2 {
|
||||
let a: string;
|
||||
let a: "Hello";
|
||||
let b: any;
|
||||
let c: string;
|
||||
let c: "Hello";
|
||||
let d: any;
|
||||
let e: any;
|
||||
}
|
||||
declare namespace n3 {
|
||||
let a: string;
|
||||
let a: "Hello" | "World";
|
||||
let b: any;
|
||||
let c: any;
|
||||
let d: any;
|
||||
let e: string;
|
||||
let e: "Hello" | "World";
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ _.compact([0, 1, false, 2, '', 3]);
|
||||
>_.compact : <T>(list: T[]) => T[]
|
||||
>_ : Underscore.Static
|
||||
>compact : <T>(list: T[]) => T[]
|
||||
>[0, 1, false, 2, '', 3] : (false | "" | 0 | 1 | 2 | 3)[]
|
||||
>[0, 1, false, 2, '', 3] : (false | 1 | 2 | 3 | 0 | "")[]
|
||||
>0 : 0
|
||||
>1 : 1
|
||||
>false : false
|
||||
|
||||
@@ -24,7 +24,7 @@ var species = foge[Symbol.species];
|
||||
>species : symbol
|
||||
|
||||
var stringTag = foge[Symbol.toStringTag];
|
||||
>stringTag : string
|
||||
>stringTag : "SharedArrayBuffer"
|
||||
>foge[Symbol.toStringTag] : "SharedArrayBuffer"
|
||||
>foge : SharedArrayBuffer
|
||||
>Symbol.toStringTag : symbol
|
||||
|
||||
@@ -15,7 +15,7 @@ var species = foge[Symbol.species];
|
||||
>species : symbol
|
||||
|
||||
var stringTag = foge[Symbol.toStringTag];
|
||||
>stringTag : string
|
||||
>stringTag : "SharedArrayBuffer"
|
||||
>foge[Symbol.toStringTag] : "SharedArrayBuffer"
|
||||
>foge : SharedArrayBuffer
|
||||
>Symbol.toStringTag : symbol
|
||||
|
||||
@@ -15,7 +15,7 @@ var species = foge[Symbol.species];
|
||||
>species : symbol
|
||||
|
||||
var stringTag = foge[Symbol.toStringTag];
|
||||
>stringTag : string
|
||||
>stringTag : "SharedArrayBuffer"
|
||||
>foge[Symbol.toStringTag] : "SharedArrayBuffer"
|
||||
>foge : SharedArrayBuffer
|
||||
>Symbol.toStringTag : symbol
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// @declaration: true
|
||||
|
||||
function f<T>(x: T): T {
|
||||
return x;
|
||||
}
|
||||
|
||||
enum E { A, B, C }
|
||||
|
||||
const c1 = "abc";
|
||||
const c2 = 123;
|
||||
const c3 = c1;
|
||||
const c4 = c2;
|
||||
const c5 = f(123);
|
||||
const c6 = f(-123);
|
||||
const c7 = true;
|
||||
const c8 = E.A;
|
||||
const c9 = { x: "abc" };
|
||||
const c10 = [123];
|
||||
const c11 = "abc" + "def";
|
||||
const c12 = 123 + 456;
|
||||
const c13 = Math.random() > 0.5 ? "abc" : "def";
|
||||
const c14 = Math.random() > 0.5 ? 123 : 456;
|
||||
@@ -0,0 +1,97 @@
|
||||
// Widening vs. non-widening literal types
|
||||
|
||||
function f1() {
|
||||
const c1 = "hello"; // Widening type "hello"
|
||||
let v1 = c1; // Type string
|
||||
const c2 = c1; // Widening type "hello"
|
||||
let v2 = c2; // Type string
|
||||
const c3: "hello" = "hello"; // Type "hello"
|
||||
let v3 = c3; // Type "hello"
|
||||
const c4: "hello" = c1; // Type "hello"
|
||||
let v4 = c4; // Type "hello"
|
||||
}
|
||||
|
||||
function f2(cond: boolean) {
|
||||
const c1 = cond ? "foo" : "bar"; // widening "foo" | widening "bar"
|
||||
const c2: "foo" | "bar" = c1; // "foo" | "bar"
|
||||
const c3 = cond ? c1 : c2; // "foo" | "bar"
|
||||
const c4 = cond ? c3 : "baz"; // "foo" | "bar" | widening "baz"
|
||||
const c5: "foo" | "bar" | "baz" = c4; // "foo" | "bar" | "baz"
|
||||
let v1 = c1; // string
|
||||
let v2 = c2; // "foo" | "bar"
|
||||
let v3 = c3; // "foo" | "bar"
|
||||
let v4 = c4; // string
|
||||
let v5 = c5; // "foo" | "bar" | "baz"
|
||||
}
|
||||
|
||||
function f3() {
|
||||
const c1 = 123; // Widening type 123
|
||||
let v1 = c1; // Type number
|
||||
const c2 = c1; // Widening type 123
|
||||
let v2 = c2; // Type number
|
||||
const c3: 123 = 123; // Type 123
|
||||
let v3 = c3; // Type 123
|
||||
const c4: 123 = c1; // Type 123
|
||||
let v4 = c4; // Type 123
|
||||
}
|
||||
|
||||
function f4(cond: boolean) {
|
||||
const c1 = cond ? 123 : 456; // widening 123 | widening 456
|
||||
const c2: 123 | 456 = c1; // 123 | 456
|
||||
const c3 = cond ? c1 : c2; // 123 | 456
|
||||
const c4 = cond ? c3 : 789; // 123 | 456 | widening 789
|
||||
const c5: 123 | 456 | 789 = c4; // 123 | 456 | 789
|
||||
let v1 = c1; // number
|
||||
let v2 = c2; // 123 | 456
|
||||
let v3 = c3; // 123 | 456
|
||||
let v4 = c4; // number
|
||||
let v5 = c5; // 123 | 456 | 789
|
||||
}
|
||||
|
||||
function f5() {
|
||||
const c1 = "foo";
|
||||
let v1 = c1;
|
||||
const c2: "foo" = "foo";
|
||||
let v2 = c2;
|
||||
const c3 = "foo" as "foo";
|
||||
let v3 = c3;
|
||||
const c4 = <"foo">"foo";
|
||||
let v4 = c4;
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type FAILURE = "FAILURE";
|
||||
const FAILURE = "FAILURE";
|
||||
|
||||
type Result<T> = T | FAILURE;
|
||||
|
||||
function doWork<T>(): Result<T> {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
function isSuccess<T>(result: Result<T>): result is T {
|
||||
return !isFailure(result);
|
||||
}
|
||||
|
||||
function isFailure<T>(result: Result<T>): result is FAILURE {
|
||||
return result === FAILURE;
|
||||
}
|
||||
|
||||
function increment(x: number): number {
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
let result = doWork<number>();
|
||||
|
||||
if (isSuccess(result)) {
|
||||
increment(result);
|
||||
}
|
||||
|
||||
// Repro from #10898
|
||||
|
||||
type TestEvent = "onmouseover" | "onmouseout";
|
||||
|
||||
function onMouseOver(): TestEvent { return "onmouseover"; }
|
||||
|
||||
let x = onMouseOver();
|
||||
Reference in New Issue
Block a user