diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16bfd7fa7e253..c18f8eb9bc23d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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((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 || 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 || 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(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(memberDecl.name); - if (t.flags & TypeFlags.Literal) { - literalName = escapeLeadingUnderscores("" + (t as LiteralType).value); + const computedType = checkComputedPropertyName(memberDecl.name); + if (isLiteralType(computedType)) { + literalName = computedType.flags & TypeFlags.Union ? + (computedType as UnionType).types.map(getTextOfPropertyLiteralType) : + getTextOfPropertyLiteralType(computedType); } } type = checkPropertyAssignment(memberDecl, checkMode); @@ -14771,72 +14795,36 @@ namespace ts { type = checkExpressionForMutableLocation((memberDecl).name, checkMode); } - 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((memberDecl).initializer)) || - (memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (memberDecl).objectAssignmentInitializer); - if (isOptional) { - prop.flags |= SymbolFlags.Optional; - } - if (!literalName && hasDynamicName(memberDecl)) { - patternWithComputedProperties = true; + if (isInJSFile) { + const jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl); + if (jsdocType) { + checkTypeAssignableTo(type, jsdocType, memberDecl); + type = jsdocType; } } - 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; + typeFlags |= type.flags; + 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 || (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((memberDecl).initializer)) || + (memberDecl.kind === SyntaxKind.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) { if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) { const name = (property).name; - if (name.kind === SyntaxKind.ComputedPropertyName) { - checkComputedPropertyName(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(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(expr.parent); const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; - return checkArrayLiteralDestructuringElementAssignment(expr.parent, typeOfArrayLiteral, - (expr.parent).elements.indexOf(expr), elementType || unknownType); + return checkArrayLiteralDestructuringElementAssignment( + expr.parent, + typeOfArrayLiteral, + (expr.parent).elements.indexOf(expr), + elementType || unknownType); } // Gets the property symbol corresponding to the property in destructuring assignment diff --git a/tests/baselines/reference/computedPropertyNames46_ES5.types b/tests/baselines/reference/computedPropertyNames46_ES5.types index e90d1a6c49864..0e8b1b345d39e 100644 --- a/tests/baselines/reference/computedPropertyNames46_ES5.types +++ b/tests/baselines/reference/computedPropertyNames46_ES5.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyNames46_ES6.types b/tests/baselines/reference/computedPropertyNames46_ES6.types index 34aac7489c9dc..68f31dc4068c9 100644 --- a/tests/baselines/reference/computedPropertyNames46_ES6.types +++ b/tests/baselines/reference/computedPropertyNames46_ES6.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyNames47_ES5.types b/tests/baselines/reference/computedPropertyNames47_ES5.types index 9c01db098467c..48029d1ad0b29 100644 --- a/tests/baselines/reference/computedPropertyNames47_ES5.types +++ b/tests/baselines/reference/computedPropertyNames47_ES5.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyNames47_ES6.types b/tests/baselines/reference/computedPropertyNames47_ES6.types index c2e65523e465b..c544096e43049 100644 --- a/tests/baselines/reference/computedPropertyNames47_ES6.types +++ b/tests/baselines/reference/computedPropertyNames47_ES6.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyNames48_ES5.types b/tests/baselines/reference/computedPropertyNames48_ES5.types index 25818fff967dd..651507d797e06 100644 --- a/tests/baselines/reference/computedPropertyNames48_ES5.types +++ b/tests/baselines/reference/computedPropertyNames48_ES5.types @@ -41,7 +41,7 @@ extractIndexer({ extractIndexer({ >extractIndexer({ ["" || 0]: ""}) : string >extractIndexer : (p: { [n: number]: T; }) => T ->{ ["" || 0]: ""} : { ["" || 0]: string; } +>{ ["" || 0]: ""} : { [0]: string; } ["" || 0]: "" >"" || 0 : 0 diff --git a/tests/baselines/reference/computedPropertyNames48_ES6.types b/tests/baselines/reference/computedPropertyNames48_ES6.types index 65f93239f30a9..e207209e48bf7 100644 --- a/tests/baselines/reference/computedPropertyNames48_ES6.types +++ b/tests/baselines/reference/computedPropertyNames48_ES6.types @@ -41,7 +41,7 @@ extractIndexer({ extractIndexer({ >extractIndexer({ ["" || 0]: ""}) : string >extractIndexer : (p: { [n: number]: T; }) => T ->{ ["" || 0]: ""} : { ["" || 0]: string; } +>{ ["" || 0]: ""} : { [0]: string; } ["" || 0]: "" >"" || 0 : 0 diff --git a/tests/baselines/reference/computedPropertyNames4_ES5.types b/tests/baselines/reference/computedPropertyNames4_ES5.types index f0e105be4a72b..c37d2b8f6b63f 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES5.types +++ b/tests/baselines/reference/computedPropertyNames4_ES5.types @@ -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, [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, [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 diff --git a/tests/baselines/reference/computedPropertyNames4_ES6.types b/tests/baselines/reference/computedPropertyNames4_ES6.types index 178eca88a72c7..90a7cc526d7c7 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES6.types +++ b/tests/baselines/reference/computedPropertyNames4_ES6.types @@ -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, [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, [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 diff --git a/tests/baselines/reference/computedPropertyNames5_ES5.types b/tests/baselines/reference/computedPropertyNames5_ES5.types index 943df91416686..d095ada7fed08 100644 --- a/tests/baselines/reference/computedPropertyNames5_ES5.types +++ b/tests/baselines/reference/computedPropertyNames5_ES5.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyNames5_ES6.types b/tests/baselines/reference/computedPropertyNames5_ES6.types index 18b522b4f6e0e..d746195d15217 100644 --- a/tests/baselines/reference/computedPropertyNames5_ES6.types +++ b/tests/baselines/reference/computedPropertyNames5_ES6.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyNames9_ES5.types b/tests/baselines/reference/computedPropertyNames9_ES5.types index 114aa4ef8128f..221f73e5ab899 100644 --- a/tests/baselines/reference/computedPropertyNames9_ES5.types +++ b/tests/baselines/reference/computedPropertyNames9_ES5.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyNames9_ES6.types b/tests/baselines/reference/computedPropertyNames9_ES6.types index d37505d863064..7830dc30fb74e 100644 --- a/tests/baselines/reference/computedPropertyNames9_ES6.types +++ b/tests/baselines/reference/computedPropertyNames9_ES6.types @@ -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 diff --git a/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.errors.txt b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.errors.txt new file mode 100644 index 0000000000000..74494b50a22b7 --- /dev/null +++ b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.errors.txt @@ -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. + } + \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.js b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.js new file mode 100644 index 0000000000000..1809ab0ac4c4a --- /dev/null +++ b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.js @@ -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; diff --git a/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.symbols b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.symbols new file mode 100644 index 0000000000000..9ea5445c99447 --- /dev/null +++ b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.symbols @@ -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)) +} + diff --git a/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.types b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.types new file mode 100644 index 0000000000000..4942e5e751f1d --- /dev/null +++ b/tests/baselines/reference/computedPropertyUnionLiftsToUnionType.types @@ -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 +>{} : {} +} + diff --git a/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.js b/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.js index 973e9756425de..1a34eb39c0ec4 100644 --- a/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.js +++ b/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.js @@ -1,5 +1,6 @@ //// [computerPropertiesInES5ShouldBeTransformed.ts] -const b = ({ [`key`]: renamed }) => renamed; +const b = ({ [`key`]: renamed }) => renamed; + //// [computerPropertiesInES5ShouldBeTransformed.js] var b = function (_a) { diff --git a/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.types b/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.types index b0e4e1424acce..8e1d05a159cb8 100644 --- a/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.types +++ b/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.types @@ -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 diff --git a/tests/baselines/reference/exportDefaultParenthesize.types b/tests/baselines/reference/exportDefaultParenthesize.types index 43e016a9ea039..e3dc8b9fdba1d 100644 --- a/tests/baselines/reference/exportDefaultParenthesize.types +++ b/tests/baselines/reference/exportDefaultParenthesize.types @@ -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" diff --git a/tests/baselines/reference/literalsInComputedProperties1.symbols b/tests/baselines/reference/literalsInComputedProperties1.symbols index 501b969706ab7..e3d47c90330c1 100644 --- a/tests/baselines/reference/literalsInComputedProperties1.symbols +++ b/tests/baselines/reference/literalsInComputedProperties1.symbols @@ -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 { diff --git a/tests/baselines/reference/literalsInComputedProperties1.types b/tests/baselines/reference/literalsInComputedProperties1.types index d258e71d6fc66..1a2246da0ac19 100644 --- a/tests/baselines/reference/literalsInComputedProperties1.types +++ b/tests/baselines/reference/literalsInComputedProperties1.types @@ -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 diff --git a/tests/baselines/reference/objectLiteralEnumPropertyNames.types b/tests/baselines/reference/objectLiteralEnumPropertyNames.types index 460d96bc56dcf..2ae3f898f3b42 100644 --- a/tests/baselines/reference/objectLiteralEnumPropertyNames.types +++ b/tests/baselines/reference/objectLiteralEnumPropertyNames.types @@ -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" diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index 1f87ed4930d24..30513ee1762ee 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -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" diff --git a/tests/baselines/reference/parserComputedPropertyName35.types b/tests/baselines/reference/parserComputedPropertyName35.types index e1be4b2ba676f..8aa053f498b79 100644 --- a/tests/baselines/reference/parserComputedPropertyName35.types +++ b/tests/baselines/reference/parserComputedPropertyName35.types @@ -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 diff --git a/tests/baselines/reference/parserComputedPropertyName41.types b/tests/baselines/reference/parserComputedPropertyName41.types index 2ef1a813a585e..8d186bd96f310 100644 --- a/tests/baselines/reference/parserComputedPropertyName41.types +++ b/tests/baselines/reference/parserComputedPropertyName41.types @@ -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 diff --git a/tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts b/tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts index 42eb602989dfe..16e3c10e9c2f6 100644 --- a/tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts +++ b/tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts @@ -1,2 +1,2 @@ // @target: es5 -const b = ({ [`key`]: renamed }) => renamed; \ No newline at end of file +const b = ({ [`key`]: renamed }) => renamed; diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts new file mode 100644 index 0000000000000..7b45df3307f82 --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyUnionLiftsToUnionType.ts @@ -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 } = {}); +} diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter index 40bdb4eadabc9..ed149eb0c787b 160000 --- a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter +++ b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter @@ -1 +1 @@ -Subproject commit 40bdb4eadabc9fbed7d83e3f26817a931c0763b6 +Subproject commit ed149eb0c787b1195a95b44105822c64bb6eb636