Compare commits

...

15 commits

Author SHA1 Message Date
Nathan Shively-Sanders cd3b688751 Fix lint:add semicolon 2018-01-09 15:07:46 -08:00
Nathan Shively-Sanders a979a0da7a Merge branch 'master' into computed-property-union-lifting 2018-01-09 15:05:00 -08:00
Nathan Shively-Sanders 85e5054857 Simplify parameter type
Let callers rely on closure instead of passing in the source type
unchanged to the lambda.
2018-01-09 14:57:59 -08:00
Nathan Shively-Sanders 772c75b3d0 Combine destructured computed property checking 2018-01-09 14:52:29 -08:00
Nathan Shively-Sanders ea8fc7c657 Computed properties with null and undefined literals 2018-01-09 14:05:00 -08:00
Nathan Shively-Sanders ddd9714d79 Error reporting:improve destructured computed properties 2018-01-09 13:20:22 -08:00
Nathan Shively-Sanders c69c4ff9c8 Improve destructuring:str/num computed properties
Also add declaration baselines for computedPropertyUnionLiftsToUnionType
2018-01-09 09:51:31 -08:00
Nathan Shively-Sanders 25f981fe73 Print computer numeric literal property names as numeric 2018-01-09 09:21:26 -08:00
Nathan Shively-Sanders 59095cdaea Further improve readability of checkObjectLiteral 2018-01-08 09:53:50 -08:00
Nathan Shively-Sanders c242f206b7 Improve spread type parameter names 2018-01-08 09:37:20 -08:00
Nathan Shively-Sanders 6bec7533a3 More computed property cases + Update baselines 2018-01-05 16:23:20 -08:00
Nathan Shively-Sanders 3123bef748 Clean up variable naming 2018-01-05 16:22:39 -08:00
Nathan Shively-Sanders d407c92ad0 Print known constants in computed property types
Also improve some names
2018-01-04 15:46:26 -08:00
Nathan Shively-Sanders b39688c278 Test literal union computed property lifting 2018-01-03 12:18:37 -08:00
Nathan Shively-Sanders 3cf0bf739e Union literal computed properties lift to union
Still uses getSpreadType (with modifications) for combining multiple
unioned computed properties. This likely has problems that will be
exposed by more tests after I write them.
2018-01-03 11:36:04 -08:00
29 changed files with 1083 additions and 154 deletions

View file

@ -2183,7 +2183,7 @@ namespace ts {
}
// A reserved member name starts with two underscores, but the third character cannot be an underscore
// or the @ symbol. A third underscore indicates an escaped form of an identifer that started
// or the @ symbol. A third underscore indicates an escaped form of an identifier that started
// with at least two underscores. The @ character indicates that the name is denoted by a well known ES
// Symbol instance.
function isReservedMemberName(name: __String) {
@ -3279,6 +3279,15 @@ namespace ts {
const declaration = symbol.declarations[0];
const name = getNameOfDeclaration(declaration);
if (name) {
if (name.kind === SyntaxKind.ComputedPropertyName &&
symbol.flags & SymbolFlags.Transient &&
!((symbol as TransientSymbol).checkFlags & CheckFlags.Late) &&
!isWellKnownSymbolSyntactically((name as ComputedPropertyName).expression) &&
symbol.escapedName !== undefined) {
return isNumericLiteralName(symbol.escapedName) ?
"[" + symbol.escapedName + "]" :
'["' + unescapeLeadingUnderscores(symbol.escapedName) + '"]';
}
return declarationNameToString(name);
}
if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) {
@ -4322,7 +4331,7 @@ namespace ts {
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false);
}
function isComputedNonLiteralName(name: PropertyName): boolean {
function isComputedNonLiteralName(name: PropertyName): name is ComputedPropertyName {
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((<ComputedPropertyName>name).expression);
}
@ -4391,22 +4400,28 @@ namespace ts {
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
const name = declaration.propertyName || <Identifier>declaration.name;
if (isComputedNonLiteralName(name)) {
// computed properties with non-literal names are treated as 'any'
return anyType;
type = checkComputedDestructuredProperty(parentType, name, text => {
const declaredType = getTypeOfPropertyOfType(parentType, text);
return declaredType && getFlowTypeOfReference(declaration, declaredType);
});
if (!type) {
return anyType;
}
}
else {
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
// or otherwise the type of the string index signature.
const text = getTextOfPropertyName(name);
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
// or otherwise the type of the string index signature.
const text = getTextOfPropertyName(name);
// Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
parentType = getNonNullableType(parentType);
// Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
parentType = getNonNullableType(parentType);
}
const declaredType = getTypeOfPropertyOfType(parentType, text);
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
getIndexTypeOfType(parentType, IndexKind.String);
}
const declaredType = getTypeOfPropertyOfType(parentType, text);
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
getIndexTypeOfType(parentType, IndexKind.String);
if (!type) {
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name));
return unknownType;
@ -4635,17 +4650,23 @@ namespace ts {
let hasComputedProperties = false;
forEach(pattern.elements, e => {
const name = e.propertyName || <Identifier>e.name;
if (isComputedNonLiteralName(name)) {
// do not include computed properties in the implied type
hasComputedProperties = true;
return;
}
let text: __String;
if (e.dotDotDotToken) {
stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
return;
}
const text = getTextOfPropertyName(name);
if (isComputedNonLiteralName(name)) {
// only include computed properties with literal types in the implied type
const computedType = checkComputedPropertyName(<ComputedPropertyName>name);
if (!computedType || !(computedType.flags & TypeFlags.Literal)) {
hasComputedProperties = true;
return;
}
text = getTextOfPropertyLiteralType(computedType);
}
else {
text = getTextOfPropertyName(name);
}
const flags = SymbolFlags.Property | (e.initializer ? SymbolFlags.Optional : 0);
const symbol = createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
@ -6095,9 +6116,13 @@ namespace ts {
getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
}
function unionSpreadIndexInfos(info1: IndexInfo, info2: IndexInfo): IndexInfo {
return info1 && info2 && createIndexInfo(
getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
function unionSpreadIndexInfos(info1: IndexInfo, info2: IndexInfo, allowSingleIndex: boolean): IndexInfo {
if (info1 && info2) {
return createIndexInfo(getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
}
if (allowSingleIndex) {
return info1 ? info1 : info2 ? info2 : undefined;
}
}
function includeMixinType(type: Type, types: Type[], index: number): Type {
@ -8478,7 +8503,7 @@ namespace ts {
* this function should be called in a left folding style, with left = previous result of getSpreadType
* and right = the new element to be spread.
*/
function getSpreadType(left: Type, right: Type, symbol: Symbol, propagatedFlags: TypeFlags): Type {
function getSpreadType(left: Type, right: Type, symbol: Symbol, propagatedFlags: TypeFlags, fromComputedProperty: boolean): Type {
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
return anyType;
}
@ -8489,10 +8514,10 @@ namespace ts {
return left;
}
if (left.flags & TypeFlags.Union) {
return mapType(left, t => getSpreadType(t, right, symbol, propagatedFlags));
return mapType(left, t => getSpreadType(t, right, symbol, propagatedFlags, fromComputedProperty));
}
if (right.flags & TypeFlags.Union) {
return mapType(right, t => getSpreadType(left, t, symbol, propagatedFlags));
return mapType(right, t => getSpreadType(left, t, symbol, propagatedFlags, fromComputedProperty));
}
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive)) {
return left;
@ -8508,8 +8533,8 @@ namespace ts {
numberIndexInfo = getIndexInfoOfType(right, IndexKind.Number);
}
else {
stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.String), getIndexInfoOfType(right, IndexKind.String));
numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.Number), getIndexInfoOfType(right, IndexKind.Number));
stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.String), getIndexInfoOfType(right, IndexKind.String), fromComputedProperty);
numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.Number), getIndexInfoOfType(right, IndexKind.Number), fromComputedProperty);
}
for (const rightProp of getPropertiesOfType(right)) {
@ -14727,7 +14752,7 @@ namespace ts {
let propertiesTable = createSymbolTable();
let propertiesArray: Symbol[] = [];
let spread: Type = emptyObjectType;
let intermediate: Type = emptyObjectType;
let propagatedFlags: TypeFlags = TypeFlags.FreshLiteral;
const contextualType = getApparentTypeOfContextualType(node);
@ -14738,27 +14763,26 @@ namespace ts {
let patternWithComputedProperties = false;
let hasComputedStringProperty = false;
let hasComputedNumberProperty = false;
let hasUnionedComputedProperty = false;
const isInJSFile = isInJavaScriptFile(node);
let offset = 0;
for (let i = 0; i < node.properties.length; i++) {
const memberDecl = node.properties[i];
let member = getSymbolOfNode(memberDecl);
let literalName: __String | undefined;
let member: Symbol;
let literalName: __String[] | __String | undefined;
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
isObjectLiteralMethod(memberDecl)) {
let jsdocType: Type;
if (isInJSFile) {
jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl);
}
let type: Type;
if (memberDecl.kind === SyntaxKind.PropertyAssignment) {
if (memberDecl.name.kind === SyntaxKind.ComputedPropertyName) {
const t = checkComputedPropertyName(<ComputedPropertyName>memberDecl.name);
if (t.flags & TypeFlags.Literal) {
literalName = escapeLeadingUnderscores("" + (t as LiteralType).value);
const computedType = checkComputedPropertyName(<ComputedPropertyName>memberDecl.name);
if (isLiteralType(computedType)) {
literalName = computedType.flags & TypeFlags.Union ?
(computedType as UnionType).types.map(getTextOfPropertyLiteralType) :
getTextOfPropertyLiteralType(computedType);
}
}
type = checkPropertyAssignment(<PropertyAssignment>memberDecl, checkMode);
@ -14771,72 +14795,36 @@ namespace ts {
type = checkExpressionForMutableLocation((<ShorthandPropertyAssignment>memberDecl).name, checkMode);
}
if (jsdocType) {
checkTypeAssignableTo(type, jsdocType, memberDecl);
type = jsdocType;
if (isInJSFile) {
const jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl);
if (jsdocType) {
checkTypeAssignableTo(type, jsdocType, memberDecl);
type = jsdocType;
}
}
typeFlags |= type.flags;
const nameType = hasLateBindableName(memberDecl) ? checkComputedPropertyName(memberDecl.name) : undefined;
const prop = nameType && isTypeUsableAsLateBoundName(nameType)
? createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType(nameType), CheckFlags.Late)
: createSymbol(SymbolFlags.Property | member.flags, literalName || member.escapedName);
if (inDestructuringPattern) {
// If object literal is an assignment pattern and if the assignment pattern specifies a default value
// for the property, make the property optional.
const isOptional =
(memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) ||
(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (<ShorthandPropertyAssignment>memberDecl).objectAssignmentInitializer);
if (isOptional) {
prop.flags |= SymbolFlags.Optional;
}
if (!literalName && hasDynamicName(memberDecl)) {
patternWithComputedProperties = true;
}
}
else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
const impliedProp = getPropertyOfType(contextualType, member.escapedName);
if (impliedProp) {
prop.flags |= impliedProp.flags & SymbolFlags.Optional;
}
else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, IndexKind.String)) {
error(memberDecl.name, Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
symbolToString(member), typeToString(contextualType));
}
}
prop.declarations = member.declarations;
prop.parent = member.parent;
if (member.valueDeclaration) {
prop.valueDeclaration = member.valueDeclaration;
if (isArray(literalName)) {
hasUnionedComputedProperty = true;
updateIntermediateType(getUnionFromLiteralUnion(memberDecl, literalName, type));
continue;
}
prop.type = type;
prop.target = member;
member = prop;
member = createProperty(memberDecl, literalName, type);
}
else if (memberDecl.kind === SyntaxKind.SpreadAssignment) {
if (languageVersion < ScriptTarget.ES2015) {
checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
}
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
propertiesArray = [];
propertiesTable = createSymbolTable();
hasComputedStringProperty = false;
hasComputedNumberProperty = false;
typeFlags = 0;
updateIntermediateType(getSpreadType(intermediate, createObjectLiteralType(), node.symbol, propagatedFlags, /*fromComputedProperty*/ false));
}
const type = checkExpression((memberDecl as SpreadAssignment).expression);
if (!isValidSpreadType(type)) {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
return unknownType;
}
spread = getSpreadType(spread, type, node.symbol, propagatedFlags);
intermediate = getSpreadType(intermediate, type, node.symbol, propagatedFlags, /*fromComputedProperty*/ false);
offset = i + 1;
continue;
}
@ -14850,6 +14838,7 @@ namespace ts {
checkNodeDeferred(memberDecl);
}
member = member || getSymbolOfNode(memberDecl);
if (!literalName && hasNonBindableDynamicName(memberDecl)) {
if (isNumericName(memberDecl.name)) {
hasComputedNumberProperty = true;
@ -14868,7 +14857,7 @@ namespace ts {
// type with those properties for which the binding pattern specifies a default value.
if (contextualTypeHasPattern) {
for (const prop of getPropertiesOfType(contextualType)) {
if (!propertiesTable.get(prop.escapedName) && !(spread && getPropertyOfType(spread, prop.escapedName))) {
if (!propertiesTable.get(prop.escapedName) && !(intermediate && getPropertyOfType(intermediate, prop.escapedName))) {
if (!(prop.flags & SymbolFlags.Optional)) {
error(prop.valueDeclaration || (<TransientSymbol>prop).bindingElement,
Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
@ -14879,15 +14868,84 @@ namespace ts {
}
}
if (spread !== emptyObjectType) {
if (intermediate !== emptyObjectType) {
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
intermediate = getSpreadType(intermediate, createObjectLiteralType(), node.symbol, propagatedFlags, /*fromComputedProperty*/ hasUnionedComputedProperty);
}
return spread;
return intermediate;
}
return createObjectLiteralType();
function updateIntermediateType(type: Type) {
intermediate = type;
propertiesArray = [];
propertiesTable = createSymbolTable();
}
function getUnionFromLiteralUnion(memberDecl: ObjectLiteralElementLike, literalNames: __String[], type: Type) {
const types: Type[] = [];
for (const literalName of literalNames) {
const prop = createProperty(memberDecl, literalName, type);
propertiesArray.push(prop);
let duplicate: Symbol;
if (propertiesTable.has(prop.escapedName)) {
duplicate = propertiesTable.get(prop.escapedName);
}
propertiesTable.set(prop.escapedName, prop);
types.push(createObjectLiteralType());
propertiesArray.pop();
if (duplicate) {
propertiesTable.set(prop.escapedName, duplicate);
}
else {
propertiesTable.delete(prop.escapedName);
}
}
return getSpreadType(intermediate, getUnionType(types), node.symbol, propagatedFlags, /*fromComputedProperty*/ true);
}
function createProperty(memberDecl: ObjectLiteralElementLike, literalName: __String, type: Type) {
const member = getSymbolOfNode(memberDecl);
const nameType = hasLateBindableName(memberDecl) ? checkComputedPropertyName(memberDecl.name) : undefined;
const prop = nameType && isTypeUsableAsLateBoundName(nameType)
? createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType(nameType), CheckFlags.Late)
: createSymbol(SymbolFlags.Property | member.flags, literalName || member.escapedName);
if (inDestructuringPattern) {
// If object literal is an assignment pattern and if the assignment pattern specifies a default value
// for the property, make the property optional.
const isOptional = (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) ||
(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (<ShorthandPropertyAssignment>memberDecl).objectAssignmentInitializer);
if (isOptional) {
prop.flags |= SymbolFlags.Optional;
}
if (!literalName && hasDynamicName(memberDecl)) {
patternWithComputedProperties = true;
}
}
else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
const impliedProp = getPropertyOfType(contextualType, member.escapedName);
if (impliedProp) {
prop.flags |= impliedProp.flags & SymbolFlags.Optional;
}
else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, IndexKind.String)) {
error(memberDecl.name, Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType));
}
}
prop.declarations = member.declarations;
prop.parent = member.parent;
if (member.valueDeclaration) {
prop.valueDeclaration = member.valueDeclaration;
}
prop.type = type;
prop.target = member;
return prop;
}
function createObjectLiteralType() {
const stringIndexInfo = isJSObjectLiteral ? jsObjectLiteralIndexInfo : hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.String) : undefined;
const numberIndexInfo = hasComputedNumberProperty && !isJSObjectLiteral ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.Number) : undefined;
@ -14908,6 +14966,13 @@ namespace ts {
}
}
function getTextOfPropertyLiteralType(type: Type): __String {
if (type.flags & TypeFlags.Intrinsic) {
return (type as IntrinsicType).intrinsicName as __String;
}
return escapeLeadingUnderscores("" + (type as LiteralType).value);
}
function isValidSpreadType(type: Type): boolean {
return !!(type.flags & (TypeFlags.Any | TypeFlags.NonPrimitive) ||
getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
@ -15014,7 +15079,7 @@ namespace ts {
else {
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, TypeFlags.JsxAttributes);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, TypeFlags.JsxAttributes, /*fromComputedProperty*/ false);
attributesTable = createSymbolTable();
}
const exprType = checkExpressionCached(attributeDecl.expression, checkMode);
@ -15022,7 +15087,7 @@ namespace ts {
hasSpreadAnyType = true;
}
if (isValidSpreadType(exprType)) {
spread = getSpreadType(spread, exprType, openingLikeElement.symbol, TypeFlags.JsxAttributes);
spread = getSpreadType(spread, exprType, openingLikeElement.symbol, TypeFlags.JsxAttributes, /*fromComputedProperty*/ false);
}
else {
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
@ -15032,7 +15097,7 @@ namespace ts {
if (!hasSpreadAnyType) {
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, TypeFlags.JsxAttributes);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, TypeFlags.JsxAttributes, /*fromComputedProperty*/ false);
}
}
@ -15057,7 +15122,7 @@ namespace ts {
createArrayType(getUnionType(childrenTypes));
const childPropMap = createSymbolTable();
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), attributes.symbol, TypeFlags.JsxAttributes);
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), attributes.symbol, TypeFlags.JsxAttributes, /*fromComputedProperty*/ false);
}
}
@ -17955,7 +18020,7 @@ namespace ts {
const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
anonymousSymbol.type = defaultContainingObject;
synthType.syntheticType = (type.flags & TypeFlags.StructuredType && type.symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable)) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*propegatedFlags*/ 0) : defaultContainingObject;
synthType.syntheticType = (type.flags & TypeFlags.StructuredType && type.symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable)) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*propagatedFlags*/ 0, /*fromComputedProperty*/ false) : defaultContainingObject;
}
else {
synthType.syntheticType = type;
@ -18779,19 +18844,23 @@ namespace ts {
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ReadonlyArray<ObjectLiteralElementLike>) {
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
const name = <PropertyName>(<PropertyAssignment>property).name;
if (name.kind === SyntaxKind.ComputedPropertyName) {
checkComputedPropertyName(<ComputedPropertyName>name);
}
let type: Type;
if (isComputedNonLiteralName(name)) {
return undefined;
type = checkComputedDestructuredProperty(objectLiteralType, name, text => {
return isTypeAny(objectLiteralType) ? anyType : getTypeOfPropertyOfType(objectLiteralType, text);
});
if (!type) {
return undefined;
}
}
else {
const text = getTextOfPropertyName(name);
type = isTypeAny(objectLiteralType)
? objectLiteralType
: getTypeOfPropertyOfType(objectLiteralType, text) ||
isNumericLiteralName(text) && getIndexTypeOfType(objectLiteralType, IndexKind.Number) ||
getIndexTypeOfType(objectLiteralType, IndexKind.String);
}
const text = getTextOfPropertyName(name);
const type = isTypeAny(objectLiteralType)
? objectLiteralType
: getTypeOfPropertyOfType(objectLiteralType, text) ||
isNumericLiteralName(text) && getIndexTypeOfType(objectLiteralType, IndexKind.Number) ||
getIndexTypeOfType(objectLiteralType, IndexKind.String);
if (type) {
if (property.kind === SyntaxKind.ShorthandPropertyAssignment) {
return checkDestructuringAssignment(<ShorthandPropertyAssignment>property, type);
@ -18823,6 +18892,39 @@ namespace ts {
}
}
function checkComputedDestructuredProperty(source: Type, name: ComputedPropertyName, getSourcePropertyType: (text: __String) => Type | undefined) {
const computedType = checkComputedPropertyName(name);
const isLiteral = isLiteralType(computedType);
const isNumeric = isLiteral && (computedType.flags & TypeFlags.NumberLiteral ||
computedType.flags & TypeFlags.Union && (computedType as UnionType).types.every(t => !!(t.flags & TypeFlags.NumberLiteral)));
let type: Type | undefined;
let errorName: __String | undefined;
if (computedType.flags & (TypeFlags.String | TypeFlags.Number) || isLiteral) {
type = getIndexTypeOfType(source, IndexKind.String);
}
if (computedType.flags & TypeFlags.Number || isNumeric) {
type = getIndexTypeOfType(source, IndexKind.Number) || type;
}
if (isLiteral) {
const text = !(computedType.flags & TypeFlags.Union) && getTextOfPropertyLiteralType(computedType);
errorName = computedType.flags & TypeFlags.Union && (computedType as UnionType).types.length ?
getTextOfPropertyLiteralType((computedType as UnionType).types[0]) :
text;
type = text && getSourcePropertyType(text) || type;
}
if (!type) {
if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
if (errorName) {
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(source), unescapeLeadingUnderscores(errorName));
}
else {
error(name, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(source));
}
}
}
return type;
}
function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, checkMode?: CheckMode): Type {
if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.Read);
@ -24839,8 +24941,11 @@ namespace ts {
// [{ property1: p1, property2 }] = elems;
const typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>expr.parent);
const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType;
return checkArrayLiteralDestructuringElementAssignment(<ArrayLiteralExpression>expr.parent, typeOfArrayLiteral,
(<ArrayLiteralExpression>expr.parent).elements.indexOf(expr), elementType || unknownType);
return checkArrayLiteralDestructuringElementAssignment(
<ArrayLiteralExpression>expr.parent,
typeOfArrayLiteral,
(<ArrayLiteralExpression>expr.parent).elements.indexOf(expr),
elementType || unknownType);
}
// Gets the property symbol corresponding to the property in destructuring assignment

View file

@ -1,7 +1,7 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames46_ES5.ts ===
var o = {
>o : { ["" || 0]: number; }
>{ ["" || 0]: 0} : { ["" || 0]: number; }
>o : { [0]: number; }
>{ ["" || 0]: 0} : { [0]: number; }
["" || 0]: 0
>"" || 0 : 0

View file

@ -1,7 +1,7 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames46_ES6.ts ===
var o = {
>o : { ["" || 0]: number; }
>{ ["" || 0]: 0} : { ["" || 0]: number; }
>o : { [0]: number; }
>{ ["" || 0]: 0} : { [0]: number; }
["" || 0]: 0
>"" || 0 : 0

View file

@ -8,8 +8,8 @@ enum E2 { x }
>x : E2
var o = {
>o : { [E1.x || E2.x]: number; }
>{ [E1.x || E2.x]: 0} : { [E1.x || E2.x]: number; }
>o : { [0]: number; }
>{ [E1.x || E2.x]: 0} : { [0]: number; }
[E1.x || E2.x]: 0
>E1.x || E2.x : E2

View file

@ -8,8 +8,8 @@ enum E2 { x }
>x : E2
var o = {
>o : { [E1.x || E2.x]: number; }
>{ [E1.x || E2.x]: 0} : { [E1.x || E2.x]: number; }
>o : { [0]: number; }
>{ [E1.x || E2.x]: 0} : { [0]: number; }
[E1.x || E2.x]: 0
>E1.x || E2.x : E2

View file

@ -41,7 +41,7 @@ extractIndexer({
extractIndexer({
>extractIndexer({ ["" || 0]: ""}) : string
>extractIndexer : <T>(p: { [n: number]: T; }) => T
>{ ["" || 0]: ""} : { ["" || 0]: string; }
>{ ["" || 0]: ""} : { [0]: string; }
["" || 0]: ""
>"" || 0 : 0

View file

@ -41,7 +41,7 @@ extractIndexer({
extractIndexer({
>extractIndexer({ ["" || 0]: ""}) : string
>extractIndexer : <T>(p: { [n: number]: T; }) => T
>{ ["" || 0]: ""} : { ["" || 0]: string; }
>{ ["" || 0]: ""} : { [0]: string; }
["" || 0]: ""
>"" || 0 : 0

View file

@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; ["hello bye"]: number; }
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; ["hello bye"]: number; }
[s]: 0,
>s : string

View file

@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; ["hello bye"]: number; }
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; ["hello bye"]: number; }
[s]: 0,
>s : string

View file

@ -3,8 +3,8 @@ var b: boolean;
>b : boolean
var v = {
>v : { [x: string]: number; [x: number]: any; [true]: number; }
>{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: string]: number; [x: number]: null; [true]: number; }
>v : { [x: string]: number; ["true"]: number; ["undefined"]: any; ["null"]: any; } | { [x: string]: number; ["true"]: number; ["undefined"]: any; ["null"]: any; ["false"]: number; }
>{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: string]: number; ["true"]: number; ["undefined"]: undefined; ["null"]: null; } | { [x: string]: number; ["true"]: number; ["undefined"]: undefined; ["null"]: null; ["false"]: number; }
[b]: 0,
>b : boolean

View file

@ -3,8 +3,8 @@ var b: boolean;
>b : boolean
var v = {
>v : { [x: string]: number; [x: number]: any; [true]: number; }
>{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: string]: number; [x: number]: null; [true]: number; }
>v : { [x: string]: number; ["true"]: number; ["undefined"]: any; ["null"]: any; } | { [x: string]: number; ["true"]: number; ["undefined"]: any; ["null"]: any; ["false"]: number; }
>{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: string]: number; ["true"]: number; ["undefined"]: undefined; ["null"]: null; } | { [x: string]: number; ["true"]: number; ["undefined"]: undefined; ["null"]: null; ["false"]: number; }
[b]: 0,
>b : boolean

View file

@ -19,8 +19,8 @@ function f(x): any { }
>x : any
var v = {
>v : { [x: string]: number; [x: number]: number; [f(true)]: number; }
>{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; [f(true)]: number; }
>v : { [x: string]: number; [x: number]: number; ["true"]: number; }
>{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; ["true"]: number; }
[f("")]: 0,
>f("") : string

View file

@ -19,8 +19,8 @@ function f(x): any { }
>x : any
var v = {
>v : { [x: string]: number; [x: number]: number; [f(true)]: number; }
>{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; [f(true)]: number; }
>v : { [x: string]: number; [x: number]: number; ["true"]: number; }
>{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; ["true"]: number; }
[f("")]: 0,
>f("") : string

View file

@ -0,0 +1,76 @@
tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts(32,4): error TS2459: Type '{ a: string; } | { b: string; }' has no property 'a' and no string index signature.
tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts(40,7): error TS2459: Type '{ a: string; } | { b: string; }' has no property 'a' and no string index signature.
tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts(58,11): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts(59,8): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
==== tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts (4 errors) ====
declare var ab: 'a' | 'b';
declare var cd: 'c' | 'd';
declare var onetwo: 1 | 2;
enum Alphabet {
Aleph,
Bet,
}
declare var alphabet: Alphabet;
const x: { a: string } | { b: string } = { [ab]: 'hi' }
// multiple unions
const y: { a: string, m: number, c: string }
| { a: string, m: number, d: string }
| { b: string, m: number, c: string }
| { b: string, m: number, d: string } = { [ab]: 'hi', m: 1, [cd]: 'there' }
// union, spread (with union inside), union
const s: { a: string, c: string } | { b: string, c: string } = { [ab]: 'hi', ...{ c: 'no' }}
const sd: { a: string } | { b: string } = { [ab]: 'hi', ...{ a: 'no' }}
const sn: { a: string, c: string }
| { a: string, d: string }
| { b: string, c: string }
| { b: string, d: string } = { [ab]: 'hi', ...{ [cd]: 'no' }}
// methods
const m: { a: string, m(): number, p: number } | { b: string, m(): number, p: number } =
{ [ab]: 'hi', m() { return 1 }, get p() { return 2 } }
// other literal types: number, enum (string and number)
const n: { "1": string } | { "2": string } = { [onetwo]: 'hi' }
const e: { "0": string } | { "1": string } = { [alphabet]: 'hi' }
// destructuring
declare let u: { a: string } | { b: string }
({ [ab]: du } = u) // implicit any error
~~~~
!!! error TS2459: Type '{ a: string; } | { b: string; }' has no property 'a' and no string index signature.
var du: any
declare let sig: { [s: string]: string }
({ [ab]: ds } = sig) // fine, comes from index signature
var ds: string
var duo: any
var dso: string
var { [ab]: duo } = u // implicit any error (or similar to the singleton one)
~~~~
!!! error TS2459: Type '{ a: string; } | { b: string; }' has no property 'a' and no string index signature.
var { [ab]: dso } = sig // fine
// number index signatures
declare let sin: { [n: number]: number }
var dn: number
({ [onetwo]: dn } = sin) // fine, from index signature
var dno: number
var { [onetwo]: dno } = sin // fine, from index signature
// # 16789
declare const textMap: {[key: string]: string}
function getText (s: string, n: number) {
var { [s]: rawText = s } = sig;
var { [n]: rawNumber = n } = sin;
({ [s]: rawText } = sig);
({ [n]: rawNumber } = sin);
var { [s]: noSig } = {};
~~~
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
({ [s]: noSig } = {});
~~~
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
}

View file

@ -0,0 +1,202 @@
//// [computedPropertyUnionLiftsToUnionType.ts]
declare var ab: 'a' | 'b';
declare var cd: 'c' | 'd';
declare var onetwo: 1 | 2;
enum Alphabet {
Aleph,
Bet,
}
declare var alphabet: Alphabet;
const x: { a: string } | { b: string } = { [ab]: 'hi' }
// multiple unions
const y: { a: string, m: number, c: string }
| { a: string, m: number, d: string }
| { b: string, m: number, c: string }
| { b: string, m: number, d: string } = { [ab]: 'hi', m: 1, [cd]: 'there' }
// union, spread (with union inside), union
const s: { a: string, c: string } | { b: string, c: string } = { [ab]: 'hi', ...{ c: 'no' }}
const sd: { a: string } | { b: string } = { [ab]: 'hi', ...{ a: 'no' }}
const sn: { a: string, c: string }
| { a: string, d: string }
| { b: string, c: string }
| { b: string, d: string } = { [ab]: 'hi', ...{ [cd]: 'no' }}
// methods
const m: { a: string, m(): number, p: number } | { b: string, m(): number, p: number } =
{ [ab]: 'hi', m() { return 1 }, get p() { return 2 } }
// other literal types: number, enum (string and number)
const n: { "1": string } | { "2": string } = { [onetwo]: 'hi' }
const e: { "0": string } | { "1": string } = { [alphabet]: 'hi' }
// destructuring
declare let u: { a: string } | { b: string }
({ [ab]: du } = u) // implicit any error
var du: any
declare let sig: { [s: string]: string }
({ [ab]: ds } = sig) // fine, comes from index signature
var ds: string
var duo: any
var dso: string
var { [ab]: duo } = u // implicit any error (or similar to the singleton one)
var { [ab]: dso } = sig // fine
// number index signatures
declare let sin: { [n: number]: number }
var dn: number
({ [onetwo]: dn } = sin) // fine, from index signature
var dno: number
var { [onetwo]: dno } = sin // fine, from index signature
// # 16789
declare const textMap: {[key: string]: string}
function getText (s: string, n: number) {
var { [s]: rawText = s } = sig;
var { [n]: rawNumber = n } = sin;
({ [s]: rawText } = sig);
({ [n]: rawNumber } = sin);
var { [s]: noSig } = {};
({ [s]: noSig } = {});
}
//// [computedPropertyUnionLiftsToUnionType.js]
var Alphabet;
(function (Alphabet) {
Alphabet[Alphabet["Aleph"] = 0] = "Aleph";
Alphabet[Alphabet["Bet"] = 1] = "Bet";
})(Alphabet || (Alphabet = {}));
const x = { [ab]: 'hi' };
// multiple unions
const y = { [ab]: 'hi', m: 1, [cd]: 'there' };
// union, spread (with union inside), union
const s = Object.assign({ [ab]: 'hi' }, { c: 'no' });
const sd = Object.assign({ [ab]: 'hi' }, { a: 'no' });
const sn = Object.assign({ [ab]: 'hi' }, { [cd]: 'no' });
// methods
const m = { [ab]: 'hi', m() { return 1; }, get p() { return 2; } };
// other literal types: number, enum (string and number)
const n = { [onetwo]: 'hi' };
const e = { [alphabet]: 'hi' };
({ [ab]: du } = u); // implicit any error
var du;
({ [ab]: ds } = sig); // fine, comes from index signature
var ds;
var duo;
var dso;
var { [ab]: duo } = u; // implicit any error (or similar to the singleton one)
var { [ab]: dso } = sig; // fine
var dn;
({ [onetwo]: dn } = sin); // fine, from index signature
var dno;
var { [onetwo]: dno } = sin; // fine, from index signature
function getText(s, n) {
var { [s]: rawText = s } = sig;
var { [n]: rawNumber = n } = sin;
({ [s]: rawText } = sig);
({ [n]: rawNumber } = sin);
var { [s]: noSig } = {};
({ [s]: noSig } = {});
}
//// [computedPropertyUnionLiftsToUnionType.d.ts]
declare var ab: 'a' | 'b';
declare var cd: 'c' | 'd';
declare var onetwo: 1 | 2;
declare enum Alphabet {
Aleph = 0,
Bet = 1,
}
declare var alphabet: Alphabet;
declare const x: {
a: string;
} | {
b: string;
};
declare const y: {
a: string;
m: number;
c: string;
} | {
a: string;
m: number;
d: string;
} | {
b: string;
m: number;
c: string;
} | {
b: string;
m: number;
d: string;
};
declare const s: {
a: string;
c: string;
} | {
b: string;
c: string;
};
declare const sd: {
a: string;
} | {
b: string;
};
declare const sn: {
a: string;
c: string;
} | {
a: string;
d: string;
} | {
b: string;
c: string;
} | {
b: string;
d: string;
};
declare const m: {
a: string;
m(): number;
p: number;
} | {
b: string;
m(): number;
p: number;
};
declare const n: {
"1": string;
} | {
"2": string;
};
declare const e: {
"0": string;
} | {
"1": string;
};
declare let u: {
a: string;
} | {
b: string;
};
declare var du: any;
declare let sig: {
[s: string]: string;
};
declare var ds: string;
declare var duo: any;
declare var dso: string;
declare var duo: any;
declare var dso: string;
declare let sin: {
[n: number]: number;
};
declare var dn: number;
declare var dno: number;
declare var dno: number;
declare const textMap: {
[key: string]: string;
};
declare function getText(s: string, n: number): void;

View file

@ -0,0 +1,218 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts ===
declare var ab: 'a' | 'b';
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
declare var cd: 'c' | 'd';
>cd : Symbol(cd, Decl(computedPropertyUnionLiftsToUnionType.ts, 1, 11))
declare var onetwo: 1 | 2;
>onetwo : Symbol(onetwo, Decl(computedPropertyUnionLiftsToUnionType.ts, 2, 11))
enum Alphabet {
>Alphabet : Symbol(Alphabet, Decl(computedPropertyUnionLiftsToUnionType.ts, 2, 26))
Aleph,
>Aleph : Symbol(Alphabet.Aleph, Decl(computedPropertyUnionLiftsToUnionType.ts, 3, 15))
Bet,
>Bet : Symbol(Alphabet.Bet, Decl(computedPropertyUnionLiftsToUnionType.ts, 4, 10))
}
declare var alphabet: Alphabet;
>alphabet : Symbol(alphabet, Decl(computedPropertyUnionLiftsToUnionType.ts, 7, 11))
>Alphabet : Symbol(Alphabet, Decl(computedPropertyUnionLiftsToUnionType.ts, 2, 26))
const x: { a: string } | { b: string } = { [ab]: 'hi' }
>x : Symbol(x, Decl(computedPropertyUnionLiftsToUnionType.ts, 9, 5))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 9, 10))
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 9, 26))
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
// multiple unions
const y: { a: string, m: number, c: string }
>y : Symbol(y, Decl(computedPropertyUnionLiftsToUnionType.ts, 11, 5))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 11, 10))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 11, 21))
>c : Symbol(c, Decl(computedPropertyUnionLiftsToUnionType.ts, 11, 32))
| { a: string, m: number, d: string }
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 12, 7))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 12, 18))
>d : Symbol(d, Decl(computedPropertyUnionLiftsToUnionType.ts, 12, 29))
| { b: string, m: number, c: string }
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 13, 7))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 13, 18))
>c : Symbol(c, Decl(computedPropertyUnionLiftsToUnionType.ts, 13, 29))
| { b: string, m: number, d: string } = { [ab]: 'hi', m: 1, [cd]: 'there' }
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 14, 7))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 14, 18))
>d : Symbol(d, Decl(computedPropertyUnionLiftsToUnionType.ts, 14, 29))
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 14, 57))
>cd : Symbol(cd, Decl(computedPropertyUnionLiftsToUnionType.ts, 1, 11))
// union, spread (with union inside), union
const s: { a: string, c: string } | { b: string, c: string } = { [ab]: 'hi', ...{ c: 'no' }}
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 16, 5))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 16, 10))
>c : Symbol(c, Decl(computedPropertyUnionLiftsToUnionType.ts, 16, 21))
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 16, 37))
>c : Symbol(c, Decl(computedPropertyUnionLiftsToUnionType.ts, 16, 48))
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>c : Symbol(c, Decl(computedPropertyUnionLiftsToUnionType.ts, 16, 81))
const sd: { a: string } | { b: string } = { [ab]: 'hi', ...{ a: 'no' }}
>sd : Symbol(sd, Decl(computedPropertyUnionLiftsToUnionType.ts, 17, 5))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 17, 11))
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 17, 27))
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 17, 60))
const sn: { a: string, c: string }
>sn : Symbol(sn, Decl(computedPropertyUnionLiftsToUnionType.ts, 18, 5))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 18, 11))
>c : Symbol(c, Decl(computedPropertyUnionLiftsToUnionType.ts, 18, 22))
| { a: string, d: string }
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 19, 7))
>d : Symbol(d, Decl(computedPropertyUnionLiftsToUnionType.ts, 19, 18))
| { b: string, c: string }
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 20, 7))
>c : Symbol(c, Decl(computedPropertyUnionLiftsToUnionType.ts, 20, 18))
| { b: string, d: string } = { [ab]: 'hi', ...{ [cd]: 'no' }}
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 21, 7))
>d : Symbol(d, Decl(computedPropertyUnionLiftsToUnionType.ts, 21, 18))
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>cd : Symbol(cd, Decl(computedPropertyUnionLiftsToUnionType.ts, 1, 11))
// methods
const m: { a: string, m(): number, p: number } | { b: string, m(): number, p: number } =
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 23, 5))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 23, 10))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 23, 21))
>p : Symbol(p, Decl(computedPropertyUnionLiftsToUnionType.ts, 23, 34))
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 23, 50))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 23, 61))
>p : Symbol(p, Decl(computedPropertyUnionLiftsToUnionType.ts, 23, 74))
{ [ab]: 'hi', m() { return 1 }, get p() { return 2 } }
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>m : Symbol(m, Decl(computedPropertyUnionLiftsToUnionType.ts, 24, 17))
>p : Symbol(p, Decl(computedPropertyUnionLiftsToUnionType.ts, 24, 35))
// other literal types: number, enum (string and number)
const n: { "1": string } | { "2": string } = { [onetwo]: 'hi' }
>n : Symbol(n, Decl(computedPropertyUnionLiftsToUnionType.ts, 26, 5))
>onetwo : Symbol(onetwo, Decl(computedPropertyUnionLiftsToUnionType.ts, 2, 11))
const e: { "0": string } | { "1": string } = { [alphabet]: 'hi' }
>e : Symbol(e, Decl(computedPropertyUnionLiftsToUnionType.ts, 27, 5))
>alphabet : Symbol(alphabet, Decl(computedPropertyUnionLiftsToUnionType.ts, 7, 11))
// destructuring
declare let u: { a: string } | { b: string }
>u : Symbol(u, Decl(computedPropertyUnionLiftsToUnionType.ts, 30, 11))
>a : Symbol(a, Decl(computedPropertyUnionLiftsToUnionType.ts, 30, 16))
>b : Symbol(b, Decl(computedPropertyUnionLiftsToUnionType.ts, 30, 32))
({ [ab]: du } = u) // implicit any error
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>du : Symbol(du, Decl(computedPropertyUnionLiftsToUnionType.ts, 32, 3))
>u : Symbol(u, Decl(computedPropertyUnionLiftsToUnionType.ts, 30, 11))
var du: any
>du : Symbol(du, Decl(computedPropertyUnionLiftsToUnionType.ts, 32, 3))
declare let sig: { [s: string]: string }
>sig : Symbol(sig, Decl(computedPropertyUnionLiftsToUnionType.ts, 33, 11))
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 33, 20))
({ [ab]: ds } = sig) // fine, comes from index signature
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>ds : Symbol(ds, Decl(computedPropertyUnionLiftsToUnionType.ts, 35, 3))
>sig : Symbol(sig, Decl(computedPropertyUnionLiftsToUnionType.ts, 33, 11))
var ds: string
>ds : Symbol(ds, Decl(computedPropertyUnionLiftsToUnionType.ts, 35, 3))
var duo: any
>duo : Symbol(duo, Decl(computedPropertyUnionLiftsToUnionType.ts, 37, 3), Decl(computedPropertyUnionLiftsToUnionType.ts, 39, 5))
var dso: string
>dso : Symbol(dso, Decl(computedPropertyUnionLiftsToUnionType.ts, 38, 3), Decl(computedPropertyUnionLiftsToUnionType.ts, 40, 5))
var { [ab]: duo } = u // implicit any error (or similar to the singleton one)
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>duo : Symbol(duo, Decl(computedPropertyUnionLiftsToUnionType.ts, 37, 3), Decl(computedPropertyUnionLiftsToUnionType.ts, 39, 5))
>u : Symbol(u, Decl(computedPropertyUnionLiftsToUnionType.ts, 30, 11))
var { [ab]: dso } = sig // fine
>ab : Symbol(ab, Decl(computedPropertyUnionLiftsToUnionType.ts, 0, 11))
>dso : Symbol(dso, Decl(computedPropertyUnionLiftsToUnionType.ts, 38, 3), Decl(computedPropertyUnionLiftsToUnionType.ts, 40, 5))
>sig : Symbol(sig, Decl(computedPropertyUnionLiftsToUnionType.ts, 33, 11))
// number index signatures
declare let sin: { [n: number]: number }
>sin : Symbol(sin, Decl(computedPropertyUnionLiftsToUnionType.ts, 43, 11))
>n : Symbol(n, Decl(computedPropertyUnionLiftsToUnionType.ts, 43, 20))
var dn: number
>dn : Symbol(dn, Decl(computedPropertyUnionLiftsToUnionType.ts, 44, 3))
({ [onetwo]: dn } = sin) // fine, from index signature
>onetwo : Symbol(onetwo, Decl(computedPropertyUnionLiftsToUnionType.ts, 2, 11))
>dn : Symbol(dn, Decl(computedPropertyUnionLiftsToUnionType.ts, 44, 3))
>sin : Symbol(sin, Decl(computedPropertyUnionLiftsToUnionType.ts, 43, 11))
var dno: number
>dno : Symbol(dno, Decl(computedPropertyUnionLiftsToUnionType.ts, 46, 3), Decl(computedPropertyUnionLiftsToUnionType.ts, 47, 5))
var { [onetwo]: dno } = sin // fine, from index signature
>onetwo : Symbol(onetwo, Decl(computedPropertyUnionLiftsToUnionType.ts, 2, 11))
>dno : Symbol(dno, Decl(computedPropertyUnionLiftsToUnionType.ts, 46, 3), Decl(computedPropertyUnionLiftsToUnionType.ts, 47, 5))
>sin : Symbol(sin, Decl(computedPropertyUnionLiftsToUnionType.ts, 43, 11))
// # 16789
declare const textMap: {[key: string]: string}
>textMap : Symbol(textMap, Decl(computedPropertyUnionLiftsToUnionType.ts, 50, 13))
>key : Symbol(key, Decl(computedPropertyUnionLiftsToUnionType.ts, 50, 25))
function getText (s: string, n: number) {
>getText : Symbol(getText, Decl(computedPropertyUnionLiftsToUnionType.ts, 50, 46))
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 18))
>n : Symbol(n, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 28))
var { [s]: rawText = s } = sig;
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 18))
>rawText : Symbol(rawText, Decl(computedPropertyUnionLiftsToUnionType.ts, 53, 9))
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 18))
>sig : Symbol(sig, Decl(computedPropertyUnionLiftsToUnionType.ts, 33, 11))
var { [n]: rawNumber = n } = sin;
>n : Symbol(n, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 28))
>rawNumber : Symbol(rawNumber, Decl(computedPropertyUnionLiftsToUnionType.ts, 54, 9))
>n : Symbol(n, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 28))
>sin : Symbol(sin, Decl(computedPropertyUnionLiftsToUnionType.ts, 43, 11))
({ [s]: rawText } = sig);
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 18))
>rawText : Symbol(rawText, Decl(computedPropertyUnionLiftsToUnionType.ts, 53, 9))
>sig : Symbol(sig, Decl(computedPropertyUnionLiftsToUnionType.ts, 33, 11))
({ [n]: rawNumber } = sin);
>n : Symbol(n, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 28))
>rawNumber : Symbol(rawNumber, Decl(computedPropertyUnionLiftsToUnionType.ts, 54, 9))
>sin : Symbol(sin, Decl(computedPropertyUnionLiftsToUnionType.ts, 43, 11))
var { [s]: noSig } = {};
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 18))
>noSig : Symbol(noSig, Decl(computedPropertyUnionLiftsToUnionType.ts, 57, 9))
({ [s]: noSig } = {});
>s : Symbol(s, Decl(computedPropertyUnionLiftsToUnionType.ts, 52, 18))
>noSig : Symbol(noSig, Decl(computedPropertyUnionLiftsToUnionType.ts, 57, 9))
}

View file

@ -0,0 +1,264 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts ===
declare var ab: 'a' | 'b';
>ab : "a" | "b"
declare var cd: 'c' | 'd';
>cd : "c" | "d"
declare var onetwo: 1 | 2;
>onetwo : 2 | 1
enum Alphabet {
>Alphabet : Alphabet
Aleph,
>Aleph : Alphabet.Aleph
Bet,
>Bet : Alphabet.Bet
}
declare var alphabet: Alphabet;
>alphabet : Alphabet
>Alphabet : Alphabet
const x: { a: string } | { b: string } = { [ab]: 'hi' }
>x : { a: string; } | { b: string; }
>a : string
>b : string
>{ [ab]: 'hi' } : { ["a"]: string; } | { ["b"]: string; }
>ab : "a" | "b"
>'hi' : "hi"
// multiple unions
const y: { a: string, m: number, c: string }
>y : { a: string; m: number; c: string; } | { a: string; m: number; d: string; } | { b: string; m: number; c: string; } | { b: string; m: number; d: string; }
>a : string
>m : number
>c : string
| { a: string, m: number, d: string }
>a : string
>m : number
>d : string
| { b: string, m: number, c: string }
>b : string
>m : number
>c : string
| { b: string, m: number, d: string } = { [ab]: 'hi', m: 1, [cd]: 'there' }
>b : string
>m : number
>d : string
>{ [ab]: 'hi', m: 1, [cd]: 'there' } : { m: number; ["c"]: string; ["a"]: string; } | { m: number; ["d"]: string; ["a"]: string; } | { m: number; ["c"]: string; ["b"]: string; } | { m: number; ["d"]: string; ["b"]: string; }
>ab : "a" | "b"
>'hi' : "hi"
>m : number
>1 : 1
>cd : "c" | "d"
>'there' : "there"
// union, spread (with union inside), union
const s: { a: string, c: string } | { b: string, c: string } = { [ab]: 'hi', ...{ c: 'no' }}
>s : { a: string; c: string; } | { b: string; c: string; }
>a : string
>c : string
>b : string
>c : string
>{ [ab]: 'hi', ...{ c: 'no' }} : { c: string; ["a"]: string; } | { c: string; ["b"]: string; }
>ab : "a" | "b"
>'hi' : "hi"
>{ c: 'no' } : { c: string; }
>c : string
>'no' : "no"
const sd: { a: string } | { b: string } = { [ab]: 'hi', ...{ a: 'no' }}
>sd : { a: string; } | { b: string; }
>a : string
>b : string
>{ [ab]: 'hi', ...{ a: 'no' }} : { a: string; } | { a: string; ["b"]: string; }
>ab : "a" | "b"
>'hi' : "hi"
>{ a: 'no' } : { a: string; }
>a : string
>'no' : "no"
const sn: { a: string, c: string }
>sn : { a: string; c: string; } | { a: string; d: string; } | { b: string; c: string; } | { b: string; d: string; }
>a : string
>c : string
| { a: string, d: string }
>a : string
>d : string
| { b: string, c: string }
>b : string
>c : string
| { b: string, d: string } = { [ab]: 'hi', ...{ [cd]: 'no' }}
>b : string
>d : string
>{ [ab]: 'hi', ...{ [cd]: 'no' }} : { ["c"]: string; ["a"]: string; } | { ["d"]: string; ["a"]: string; } | { ["c"]: string; ["b"]: string; } | { ["d"]: string; ["b"]: string; }
>ab : "a" | "b"
>'hi' : "hi"
>{ [cd]: 'no' } : { ["c"]: string; } | { ["d"]: string; }
>cd : "c" | "d"
>'no' : "no"
// methods
const m: { a: string, m(): number, p: number } | { b: string, m(): number, p: number } =
>m : { a: string; m(): number; p: number; } | { b: string; m(): number; p: number; }
>a : string
>m : () => number
>p : number
>b : string
>m : () => number
>p : number
{ [ab]: 'hi', m() { return 1 }, get p() { return 2 } }
>{ [ab]: 'hi', m() { return 1 }, get p() { return 2 } } : { m(): number; p: number; ["a"]: string; } | { m(): number; p: number; ["b"]: string; }
>ab : "a" | "b"
>'hi' : "hi"
>m : () => number
>1 : 1
>p : number
>2 : 2
// other literal types: number, enum (string and number)
const n: { "1": string } | { "2": string } = { [onetwo]: 'hi' }
>n : { "1": string; } | { "2": string; }
>{ [onetwo]: 'hi' } : { [2]: string; } | { [1]: string; }
>onetwo : 2 | 1
>'hi' : "hi"
const e: { "0": string } | { "1": string } = { [alphabet]: 'hi' }
>e : { "0": string; } | { "1": string; }
>{ [alphabet]: 'hi' } : { [0]: string; } | { [1]: string; }
>alphabet : Alphabet
>'hi' : "hi"
// destructuring
declare let u: { a: string } | { b: string }
>u : { a: string; } | { b: string; }
>a : string
>b : string
({ [ab]: du } = u) // implicit any error
>({ [ab]: du } = u) : { a: string; } | { b: string; }
>{ [ab]: du } = u : { a: string; } | { b: string; }
>{ [ab]: du } : { ["a"]: any; } | { ["b"]: any; }
>ab : "a" | "b"
>du : any
>u : { a: string; } | { b: string; }
var du: any
>du : any
declare let sig: { [s: string]: string }
>sig : { [s: string]: string; }
>s : string
({ [ab]: ds } = sig) // fine, comes from index signature
>({ [ab]: ds } = sig) : { [s: string]: string; }
>{ [ab]: ds } = sig : { [s: string]: string; }
>{ [ab]: ds } : { ["a"]: string; } | { ["b"]: string; }
>ab : "a" | "b"
>ds : string
>sig : { [s: string]: string; }
var ds: string
>ds : string
var duo: any
>duo : any
var dso: string
>dso : string
var { [ab]: duo } = u // implicit any error (or similar to the singleton one)
>ab : "a" | "b"
>duo : any
>u : { a: string; } | { b: string; }
var { [ab]: dso } = sig // fine
>ab : "a" | "b"
>dso : string
>sig : { [s: string]: string; }
// number index signatures
declare let sin: { [n: number]: number }
>sin : { [n: number]: number; }
>n : number
var dn: number
>dn : number
({ [onetwo]: dn } = sin) // fine, from index signature
>({ [onetwo]: dn } = sin) : { [n: number]: number; }
>{ [onetwo]: dn } = sin : { [n: number]: number; }
>{ [onetwo]: dn } : { [2]: number; } | { [1]: number; }
>onetwo : 2 | 1
>dn : number
>sin : { [n: number]: number; }
var dno: number
>dno : number
var { [onetwo]: dno } = sin // fine, from index signature
>onetwo : 2 | 1
>dno : number
>sin : { [n: number]: number; }
// # 16789
declare const textMap: {[key: string]: string}
>textMap : { [key: string]: string; }
>key : string
function getText (s: string, n: number) {
>getText : (s: string, n: number) => void
>s : string
>n : number
var { [s]: rawText = s } = sig;
>s : string
>rawText : string
>s : string
>sig : { [s: string]: string; }
var { [n]: rawNumber = n } = sin;
>n : number
>rawNumber : number
>n : number
>sin : { [n: number]: number; }
({ [s]: rawText } = sig);
>({ [s]: rawText } = sig) : { [s: string]: string; }
>{ [s]: rawText } = sig : { [s: string]: string; }
>{ [s]: rawText } : { [x: string]: string; }
>s : string
>rawText : string
>sig : { [s: string]: string; }
({ [n]: rawNumber } = sin);
>({ [n]: rawNumber } = sin) : { [n: number]: number; }
>{ [n]: rawNumber } = sin : { [n: number]: number; }
>{ [n]: rawNumber } : { [x: number]: number; }
>n : number
>rawNumber : number
>sin : { [n: number]: number; }
var { [s]: noSig } = {};
>s : string
>noSig : any
>{} : {}
({ [s]: noSig } = {});
>({ [s]: noSig } = {}) : {}
>{ [s]: noSig } = {} : {}
>{ [s]: noSig } : { [x: string]: any; }
>s : string
>noSig : any
>{} : {}
}

View file

@ -1,5 +1,6 @@
//// [computerPropertiesInES5ShouldBeTransformed.ts]
const b = ({ [`key`]: renamed }) => renamed;
const b = ({ [`key`]: renamed }) => renamed;
//// [computerPropertiesInES5ShouldBeTransformed.js]
var b = function (_a) {

View file

@ -1,7 +1,7 @@
=== tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts ===
const b = ({ [`key`]: renamed }) => renamed;
>b : ({ [`key`]: renamed }: {}) => any
>({ [`key`]: renamed }) => renamed : ({ [`key`]: renamed }: {}) => any
>b : ({ [`key`]: renamed }: { key: any; }) => any
>({ [`key`]: renamed }) => renamed : ({ [`key`]: renamed }: { key: any; }) => any
>`key` : "key"
>renamed : any
>renamed : any

View file

@ -144,7 +144,7 @@ export default {
=== tests/cases/compiler/comma.ts ===
export default {
>{ ['foo']: 42} : { ['foo']: number; }
>{ ['foo']: 42} : { ["foo"]: number; }
['foo']: 42
>'foo' : "foo"

View file

@ -31,7 +31,7 @@ x[3].toExponential();
x[4].toExponential();
>x[4].toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
>x : Symbol(x, Decl(literalsInComputedProperties1.ts, 0, 3))
>4 : Symbol(["4"], Decl(literalsInComputedProperties1.ts, 3, 10))
>4 : Symbol([4], Decl(literalsInComputedProperties1.ts, 3, 10))
>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
interface A {

View file

@ -1,7 +1,7 @@
=== tests/cases/compiler/literalsInComputedProperties1.ts ===
let x = {
>x : { 1: number; [2]: number; "3": number; ["4"]: number; }
>{ 1:1, [2]:1, "3":1, ["4"]:1} : { 1: number; [2]: number; "3": number; ["4"]: number; }
>x : { 1: number; [2]: number; "3": number; [4]: number; }
>{ 1:1, [2]:1, "3":1, ["4"]:1} : { 1: number; [2]: number; "3": number; [4]: number; }
1:1,
>1 : 1
@ -21,7 +21,7 @@ x[1].toExponential();
>x[1].toExponential() : string
>x[1].toExponential : (fractionDigits?: number) => string
>x[1] : number
>x : { 1: number; [2]: number; "3": number; ["4"]: number; }
>x : { 1: number; [2]: number; "3": number; [4]: number; }
>1 : 1
>toExponential : (fractionDigits?: number) => string
@ -29,7 +29,7 @@ x[2].toExponential();
>x[2].toExponential() : string
>x[2].toExponential : (fractionDigits?: number) => string
>x[2] : number
>x : { 1: number; [2]: number; "3": number; ["4"]: number; }
>x : { 1: number; [2]: number; "3": number; [4]: number; }
>2 : 2
>toExponential : (fractionDigits?: number) => string
@ -37,7 +37,7 @@ x[3].toExponential();
>x[3].toExponential() : string
>x[3].toExponential : (fractionDigits?: number) => string
>x[3] : number
>x : { 1: number; [2]: number; "3": number; ["4"]: number; }
>x : { 1: number; [2]: number; "3": number; [4]: number; }
>3 : 3
>toExponential : (fractionDigits?: number) => string
@ -45,7 +45,7 @@ x[4].toExponential();
>x[4].toExponential() : string
>x[4].toExponential : (fractionDigits?: number) => string
>x[4] : number
>x : { 1: number; [2]: number; "3": number; ["4"]: number; }
>x : { 1: number; [2]: number; "3": number; [4]: number; }
>4 : 4
>toExponential : (fractionDigits?: number) => string

View file

@ -52,7 +52,7 @@ const ux = {
const y: TestStrs = {
>y : TestStrs
>TestStrs : TestStrs
>{ ['a']: 'yo', ['b']: 'ye'} : { ['a']: string; ['b']: string; }
>{ ['a']: 'yo', ['b']: 'ye'} : { ["a"]: string; ["b"]: string; }
['a']: 'yo',
>'a' : "a"

View file

@ -521,7 +521,7 @@ function container(
>b : string
{ ['before everything']: 12, ...o, b: 'yes' }
>{ ['before everything']: 12, ...o, b: 'yes' } : { b: string; a: number; ['before everything']: number; }
>{ ['before everything']: 12, ...o, b: 'yes' } : { b: string; a: number; ["before everything"]: number; }
>'before everything' : "before everything"
>12 : 12
>o : { a: number; b: string; }
@ -535,7 +535,7 @@ function container(
>c : boolean
{ ...o, ['in the middle']: 13, b: 'maybe?', ...o2 }
>{ ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } : { b: string; c: boolean; ['in the middle']: number; a: number; }
>{ ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } : { b: string; c: boolean; ["in the middle"]: number; a: number; }
>o : { a: number; b: string; }
>'in the middle' : "in the middle"
>13 : 13
@ -549,7 +549,7 @@ function container(
>b : string
{ ...o, b: 'yeah', ['at the end']: 14 }
>{ ...o, b: 'yeah', ['at the end']: 14 } : { b: string; ['at the end']: number; a: number; }
>{ ...o, b: 'yeah', ['at the end']: 14 } : { b: string; ["at the end"]: number; a: number; }
>o : { a: number; b: string; }
>b : string
>'yeah' : "yeah"

View file

@ -1,7 +1,7 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName35.ts ===
var x = {
>x : { [0, 1]: {}; }
>{ [0, 1]: { }} : { [0, 1]: {}; }
>x : { [1]: {}; }
>{ [0, 1]: { }} : { [1]: {}; }
[0, 1]: { }
>0, 1 : 1

View file

@ -1,7 +1,7 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName41.ts ===
var v = {
>v : { [x: string]: boolean; }
>{ [0 in []]: true} : { [x: string]: boolean; }
>v : { ["true"]: boolean; } | { ["false"]: boolean; }
>{ [0 in []]: true} : { ["true"]: boolean; } | { ["false"]: boolean; }
[0 in []]: true
>0 in [] : boolean

View file

@ -1,2 +1,2 @@
// @target: es5
const b = ({ [`key`]: renamed }) => renamed;
const b = ({ [`key`]: renamed }) => renamed;

View file

@ -0,0 +1,63 @@
// @noImplicitAny: true
// @target: es6
// @declaration: true
declare var ab: 'a' | 'b';
declare var cd: 'c' | 'd';
declare var onetwo: 1 | 2;
enum Alphabet {
Aleph,
Bet,
}
declare var alphabet: Alphabet;
const x: { a: string } | { b: string } = { [ab]: 'hi' }
// multiple unions
const y: { a: string, m: number, c: string }
| { a: string, m: number, d: string }
| { b: string, m: number, c: string }
| { b: string, m: number, d: string } = { [ab]: 'hi', m: 1, [cd]: 'there' }
// union, spread (with union inside), union
const s: { a: string, c: string } | { b: string, c: string } = { [ab]: 'hi', ...{ c: 'no' }}
const sd: { a: string } | { b: string } = { [ab]: 'hi', ...{ a: 'no' }}
const sn: { a: string, c: string }
| { a: string, d: string }
| { b: string, c: string }
| { b: string, d: string } = { [ab]: 'hi', ...{ [cd]: 'no' }}
// methods
const m: { a: string, m(): number, p: number } | { b: string, m(): number, p: number } =
{ [ab]: 'hi', m() { return 1 }, get p() { return 2 } }
// other literal types: number, enum (string and number)
const n: { "1": string } | { "2": string } = { [onetwo]: 'hi' }
const e: { "0": string } | { "1": string } = { [alphabet]: 'hi' }
// destructuring
declare let u: { a: string } | { b: string }
({ [ab]: du } = u) // implicit any error
var du: any
declare let sig: { [s: string]: string }
({ [ab]: ds } = sig) // fine, comes from index signature
var ds: string
var duo: any
var dso: string
var { [ab]: duo } = u // implicit any error (or similar to the singleton one)
var { [ab]: dso } = sig // fine
// number index signatures
declare let sin: { [n: number]: number }
var dn: number
({ [onetwo]: dn } = sin) // fine, from index signature
var dno: number
var { [onetwo]: dno } = sin // fine, from index signature
// # 16789
declare const textMap: {[key: string]: string}
function getText (s: string, n: number) {
var { [s]: rawText = s } = sig;
var { [n]: rawNumber = n } = sin;
({ [s]: rawText } = sig);
({ [n]: rawNumber } = sin);
var { [s]: noSig } = {};
({ [s]: noSig } = {});
}

@ -1 +1 @@
Subproject commit 40bdb4eadabc9fbed7d83e3f26817a931c0763b6
Subproject commit ed149eb0c787b1195a95b44105822c64bb6eb636