diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index acf5125aa9bc6..b2b34d7aec185 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4768,6 +4768,69 @@ namespace ts { return createAnonymousType(symbol, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); } + // Determine the control flow type associated with a destructuring declaration or assignment. The following + // forms of destructuring are possible: + // let { x } = obj; // BindingElement + // let [ x ] = obj; // BindingElement + // { x } = obj; // ShorthandPropertyAssignment + // { x: v } = obj; // PropertyAssignment + // [ x ] = obj; // Expression + // We construct a synthetic element access expression corresponding to 'obj.x' such that the control + // flow analyzer doesn't have to handle all the different syntactic forms. + function getFlowTypeOfDestructuring(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression, declaredType: Type) { + const reference = getSyntheticElementAccess(node); + return reference ? getFlowTypeOfReference(reference, declaredType) : declaredType; + } + + function getSyntheticElementAccess(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression): ElementAccessExpression | undefined { + const parentAccess = getParentElementAccess(node); + if (parentAccess && parentAccess.flowNode) { + const propName = getDestructuringPropertyName(node); + if (propName) { + const result = createNode(SyntaxKind.ElementAccessExpression, node.pos, node.end); + result.parent = node; + result.expression = parentAccess; + const literal = createNode(SyntaxKind.StringLiteral, node.pos, node.end); + literal.parent = result; + literal.text = propName; + result.argumentExpression = literal; + result.flowNode = parentAccess.flowNode; + return result; + } + } + } + + function getParentElementAccess(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression) { + const ancestor = node.parent.parent; + switch (ancestor.kind) { + case SyntaxKind.BindingElement: + case SyntaxKind.PropertyAssignment: + return getSyntheticElementAccess(ancestor); + case SyntaxKind.ArrayLiteralExpression: + return getSyntheticElementAccess(node.parent); + case SyntaxKind.VariableDeclaration: + return (ancestor).initializer; + case SyntaxKind.BinaryExpression: + return (ancestor).right; + } + } + + function getDestructuringPropertyName(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression) { + const parent = node.parent; + if (node.kind === SyntaxKind.BindingElement && parent.kind === SyntaxKind.ObjectBindingPattern) { + return getLiteralPropertyNameText((node).propertyName || (node).name); + } + if (node.kind === SyntaxKind.PropertyAssignment || node.kind === SyntaxKind.ShorthandPropertyAssignment) { + return getLiteralPropertyNameText((node).name); + } + return "" + (>(parent).elements).indexOf(node); + } + + function getLiteralPropertyNameText(name: PropertyName) { + const type = getLiteralTypeFromPropertyName(name); + return type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral) ? "" + (type).value : undefined; + } + /** Return the inferred type for a binding element */ function getTypeForBindingElement(declaration: BindingElement): Type | undefined { const pattern = declaration.parent; @@ -4808,9 +4871,9 @@ namespace ts { else { // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) const name = declaration.propertyName || declaration.name; - const exprType = getLiteralTypeFromPropertyName(name); - const declaredType = checkIndexedAccessIndexType(getIndexedAccessType(parentType, exprType, name), name); - type = getFlowTypeOfReference(declaration, getConstraintForLocation(declaredType, declaration.name)); + const indexType = getLiteralTypeFromPropertyName(name); + const declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, name), declaration.name); + type = getFlowTypeOfDestructuring(declaration, declaredType); } } else { @@ -4827,21 +4890,13 @@ namespace ts { mapType(parentType, t => sliceTupleType(t, index)) : createArrayType(elementType); } + else if (isArrayLikeType(parentType)) { + const indexType = getLiteralType(index); + const declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, declaration.name), declaration.name); + type = getFlowTypeOfDestructuring(declaration, declaredType); + } else { - // Use specific property type when parent is a tuple or numeric index type when parent is an array - const index = pattern.elements.indexOf(declaration); - type = everyType(parentType, isTupleLikeType) ? - getTupleElementType(parentType, index) || declaration.initializer && checkDeclarationInitializer(declaration) : - elementType; - if (!type) { - if (isTupleType(parentType)) { - error(declaration, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(parentType), pattern.elements.length); - } - else { - error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), "" + index); - } - return errorType; - } + type = elementType; } } // In strict null checking mode, if a default value of a non-undefined type is specified, remove @@ -9523,16 +9578,16 @@ namespace ts { return false; } - function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | undefined, cacheSymbol: boolean, missingType: Type) { + function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, cacheSymbol: boolean, missingType: Type) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; - const propName = isTypeUsableAsLateBoundName(indexType) - ? getLateBoundNameFromType(indexType) - : accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) - ? getPropertyNameForKnownSymbolName(idText((accessExpression.argumentExpression).name)) - : accessNode && isPropertyName(accessNode) + const propName = isTypeUsableAsLateBoundName(indexType) ? + getLateBoundNameFromType(indexType) : + accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ? + getPropertyNameForKnownSymbolName(idText((accessExpression.argumentExpression).name)) : + accessNode && isPropertyName(accessNode) ? // late bound names are handled in the first branch, so here we only need to handle normal names - ? getPropertyNameForPropertyNameNode(accessNode) - : undefined; + getPropertyNameForPropertyNameNode(accessNode) : + undefined; if (propName !== undefined) { const prop = getPropertyOfType(objectType, propName); if (prop) { @@ -9554,7 +9609,13 @@ namespace ts { if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) { if (accessNode && everyType(objectType, t => !(t).target.hasRestElement)) { const indexNode = getIndexNodeForAccessExpression(accessNode); - error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); + if (isTupleType(objectType)) { + error(indexNode, Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, + typeToString(objectType), getTypeReferenceArity(objectType), unescapeLeadingUnderscores(propName)); + } + else { + error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); + } } return mapType(objectType, t => getRestTypeOfTupleType(t) || undefinedType); } @@ -9626,7 +9687,7 @@ namespace ts { return missingType; } - function getIndexNodeForAccessExpression(accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName) { + function getIndexNodeForAccessExpression(accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression) { return accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.kind === SyntaxKind.IndexedAccessType @@ -9695,7 +9756,7 @@ namespace ts { return type.simplified = type; } - function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName, missingType = accessNode ? errorType : unknownType): Type { + function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, missingType = accessNode ? errorType : unknownType): Type { if (objectType === wildcardType || indexType === wildcardType) { return wildcardType; } @@ -14569,49 +14630,23 @@ namespace ts { // occurring in an apparent type position with '@' because the control flow type // of such nodes may be based on the apparent type instead of the declared type. function getFlowCacheKey(node: Node): string | undefined { - if (node.kind === SyntaxKind.Identifier) { - const symbol = getResolvedSymbol(node); - return symbol !== unknownSymbol ? (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined; - } - if (node.kind === SyntaxKind.ThisKeyword) { - return "0"; - } - if (node.kind === SyntaxKind.PropertyAccessExpression) { - const key = getFlowCacheKey((node).expression); - return key && key + "." + idText((node).name); - } - if (node.kind === SyntaxKind.BindingElement) { - const container = (node as BindingElement).parent.parent; - const key = container.kind === SyntaxKind.BindingElement ? getFlowCacheKey(container) : (container.initializer && getFlowCacheKey(container.initializer)); - const text = getBindingElementNameText(node as BindingElement); - const result = key && text && (key + "." + text); - return result; + switch (node.kind) { + case SyntaxKind.Identifier: + const symbol = getResolvedSymbol(node); + return symbol !== unknownSymbol ? (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined; + case SyntaxKind.ThisKeyword: + return "0"; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + const propName = getAccessedPropertyName(node); + if (propName !== undefined) { + const key = getFlowCacheKey((node).expression); + return key && key + "." + propName; + } } return undefined; } - function getBindingElementNameText(element: BindingElement): string | undefined { - const parent = element.parent; - if (parent.kind === SyntaxKind.ObjectBindingPattern) { - const name = element.propertyName || element.name; - switch (name.kind) { - case SyntaxKind.Identifier: - return idText(name); - case SyntaxKind.ComputedPropertyName: - return isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined; - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - return name.text; - default: - // Per types, array and object binding patterns remain, however they should never be present if propertyName is not defined - Debug.fail("Unexpected name kind for binding element name"); - } - } - else { - return "" + parent.elements.indexOf(element); - } - } - function isMatchingReference(source: Node, target: Node): boolean { switch (source.kind) { case SyntaxKind.Identifier: @@ -14624,49 +14659,27 @@ namespace ts { return target.kind === SyntaxKind.SuperKeyword; case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: - return (isPropertyAccessExpression(target) || isElementAccessExpression(target)) && - getAccessedPropertyName(source as PropertyAccessExpression | ElementAccessExpression) === getAccessedPropertyName(target) && - isMatchingReference((source as PropertyAccessExpression | ElementAccessExpression).expression, target.expression); - case SyntaxKind.BindingElement: - if (target.kind === SyntaxKind.PropertyAccessExpression && (target).name.escapedText === getBindingElementNameText(source)) { - const ancestor = source.parent.parent; - if (ancestor.kind === SyntaxKind.BindingElement) { - return isMatchingReference(ancestor, (target).expression); - } - if (ancestor.kind === SyntaxKind.VariableDeclaration) { - const initializer = (ancestor).initializer; - return !!initializer && isMatchingReference(initializer, (target).expression); - } - } + return isAccessExpression(target) && + getAccessedPropertyName(source) === getAccessedPropertyName(target) && + isMatchingReference((source).expression, target.expression); } return false; } - function getAccessedPropertyName(access: PropertyAccessExpression | ElementAccessExpression): __String | undefined { - return isPropertyAccessExpression(access) ? access.name.escapedText : + function getAccessedPropertyName(access: AccessExpression): __String | undefined { + return access.kind === SyntaxKind.PropertyAccessExpression ? access.name.escapedText : isStringLiteral(access.argumentExpression) || isNumericLiteral(access.argumentExpression) ? escapeLeadingUnderscores(access.argumentExpression.text) : undefined; } - function getReferenceParent(source: Node) { - if (source.kind === SyntaxKind.PropertyAccessExpression) { - return (source).expression; - } - if (source.kind === SyntaxKind.BindingElement) { - const ancestor = source.parent.parent; - return ancestor.kind === SyntaxKind.VariableDeclaration ? (ancestor).initializer : ancestor; - } - return undefined; - } - function containsMatchingReference(source: Node, target: Node) { - let parent = getReferenceParent(source); - while (parent) { - if (isMatchingReference(parent, target)) { + while (isAccessExpression(source)) { + source = source.expression; + if (isMatchingReference(source, target)) { return true; } - parent = getReferenceParent(parent); } + return false; } // Return true if target is a property access xxx.yyy, source is a property access xxx.zzz, the declared @@ -14674,18 +14687,23 @@ namespace ts { // a possible discriminant if its type differs in the constituents of containing union type, and if every // choice is a unit type or a union of unit types. function containsMatchingReferenceDiscriminant(source: Node, target: Node) { - return target.kind === SyntaxKind.PropertyAccessExpression && - containsMatchingReference(source, (target).expression) && - isDiscriminantProperty(getDeclaredTypeOfReference((target).expression), (target).name.escapedText); + let name; + return isAccessExpression(target) && + containsMatchingReference(source, target.expression) && + (name = getAccessedPropertyName(target)) !== undefined && + isDiscriminantProperty(getDeclaredTypeOfReference(target.expression), name); } function getDeclaredTypeOfReference(expr: Node): Type | undefined { if (expr.kind === SyntaxKind.Identifier) { return getTypeOfSymbol(getResolvedSymbol(expr)); } - if (expr.kind === SyntaxKind.PropertyAccessExpression) { - const type = getDeclaredTypeOfReference((expr).expression); - return type && getTypeOfPropertyOfType(type, (expr).name.escapedText); + if (isAccessExpression(expr)) { + const type = getDeclaredTypeOfReference(expr.expression); + if (type) { + const propName = getAccessedPropertyName(expr); + return propName !== undefined ? getTypeOfPropertyOfType(type, propName) : undefined; + } } return undefined; } @@ -15511,7 +15529,7 @@ namespace ts { else if (isMatchingReferenceDiscriminant(expr, type)) { type = narrowTypeByDiscriminant( type, - expr as PropertyAccessExpression | ElementAccessExpression, + expr as AccessExpression, t => narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd)); } else if (expr.kind === SyntaxKind.TypeOfExpression && isMatchingReference(reference, (expr as TypeOfExpression).expression)) { @@ -15631,21 +15649,19 @@ namespace ts { } function isMatchingReferenceDiscriminant(expr: Expression, computedType: Type) { - if (!(computedType.flags & TypeFlags.Union) || - expr.kind !== SyntaxKind.PropertyAccessExpression && expr.kind !== SyntaxKind.ElementAccessExpression) { + if (!(computedType.flags & TypeFlags.Union) || !isAccessExpression(expr)) { return false; } - const access = expr as PropertyAccessExpression | ElementAccessExpression; - const name = getAccessedPropertyName(access); - if (!name) { + const name = getAccessedPropertyName(expr); + if (name === undefined) { return false; } - return isMatchingReference(reference, access.expression) && isDiscriminantProperty(computedType, name); + return isMatchingReference(reference, expr.expression) && isDiscriminantProperty(computedType, name); } - function narrowTypeByDiscriminant(type: Type, access: PropertyAccessExpression | ElementAccessExpression, narrowType: (t: Type) => Type): Type { + function narrowTypeByDiscriminant(type: Type, access: AccessExpression, narrowType: (t: Type) => Type): Type { const propName = getAccessedPropertyName(access); - if (!propName) { + if (propName === undefined) { return type; } const propType = getTypeOfPropertyOfType(type, propName); @@ -15658,7 +15674,7 @@ namespace ts { return getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy); } if (isMatchingReferenceDiscriminant(expr, declaredType)) { - return narrowTypeByDiscriminant(type, expr, t => getTypeWithFacts(t, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy)); + return narrowTypeByDiscriminant(type, expr, t => getTypeWithFacts(t, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy)); } if (containsMatchingReferenceDiscriminant(reference, expr)) { return declaredType; @@ -15709,10 +15725,10 @@ namespace ts { return narrowTypeByEquality(type, operator, left, assumeTrue); } if (isMatchingReferenceDiscriminant(left, declaredType)) { - return narrowTypeByDiscriminant(type, left, t => narrowTypeByEquality(t, operator, right, assumeTrue)); + return narrowTypeByDiscriminant(type, left, t => narrowTypeByEquality(t, operator, right, assumeTrue)); } if (isMatchingReferenceDiscriminant(right, declaredType)) { - return narrowTypeByDiscriminant(type, right, t => narrowTypeByEquality(t, operator, left, assumeTrue)); + return narrowTypeByDiscriminant(type, right, t => narrowTypeByEquality(t, operator, left, assumeTrue)); } if (containsMatchingReferenceDiscriminant(reference, left) || containsMatchingReferenceDiscriminant(reference, right)) { return declaredType; @@ -16017,9 +16033,8 @@ namespace ts { } else { const invokedExpression = skipParentheses(callExpression.expression); - if (invokedExpression.kind === SyntaxKind.ElementAccessExpression || invokedExpression.kind === SyntaxKind.PropertyAccessExpression) { - const accessExpression = invokedExpression as ElementAccessExpression | PropertyAccessExpression; - const possibleReference = skipParentheses(accessExpression.expression); + if (isAccessExpression(invokedExpression)) { + const possibleReference = skipParentheses(invokedExpression.expression); if (isMatchingReference(reference, possibleReference)) { return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf); } @@ -16962,7 +16977,7 @@ namespace ts { if (parent.kind === SyntaxKind.BinaryExpression && (parent).operatorToken.kind === SyntaxKind.EqualsToken) { const target = (parent).left; if (target.kind === SyntaxKind.PropertyAccessExpression || target.kind === SyntaxKind.ElementAccessExpression) { - const { expression } = target as PropertyAccessExpression | ElementAccessExpression; + const { expression } = target as AccessExpression; // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }` if (inJs && isIdentifier(expression)) { const sourceFile = getSourceFileOfNode(parent); @@ -19711,7 +19726,7 @@ namespace ts { if (node.kind === SyntaxKind.CallExpression) { const callee = skipOuterExpressions(node.expression); if (callee.kind === SyntaxKind.PropertyAccessExpression || callee.kind === SyntaxKind.ElementAccessExpression) { - return (callee as PropertyAccessExpression | ElementAccessExpression).expression; + return (callee as AccessExpression).expression; } } } @@ -21743,7 +21758,7 @@ namespace ts { // Allow assignments to readonly properties within constructors of the same class declaration. if (symbol.flags & SymbolFlags.Property && (expr.kind === SyntaxKind.PropertyAccessExpression || expr.kind === SyntaxKind.ElementAccessExpression) && - (expr as PropertyAccessExpression | ElementAccessExpression).expression.kind === SyntaxKind.ThisKeyword) { + (expr as AccessExpression).expression.kind === SyntaxKind.ThisKeyword) { // Look for if this is the constructor for the class that `symbol` is a property of. const func = getContainingFunction(expr); if (!(func && func.kind === SyntaxKind.Constructor)) { @@ -21761,7 +21776,7 @@ namespace ts { function isReferenceThroughNamespaceImport(expr: Expression): boolean { if (expr.kind === SyntaxKind.PropertyAccessExpression || expr.kind === SyntaxKind.ElementAccessExpression) { - const node = skipParentheses((expr as PropertyAccessExpression | ElementAccessExpression).expression); + const node = skipParentheses((expr as AccessExpression).expression); if (node.kind === SyntaxKind.Identifier) { const symbol = getNodeLinks(node).resolvedSymbol!; if (symbol.flags & SymbolFlags.Alias) { @@ -22010,21 +22025,18 @@ namespace ts { function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: NodeArray, rightIsThis = false) { if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) { const name = property.name; - if (name.kind === SyntaxKind.ComputedPropertyName) { - checkComputedPropertyName(name); - } - if (isComputedNonLiteralName(name)) { - return undefined; - } - - const type = getTypeOfObjectLiteralDestructuringProperty(objectLiteralType, name, property, rightIsThis); - if (type) { - // non-shorthand property assignments should always have initializers - return checkDestructuringAssignment(property.kind === SyntaxKind.ShorthandPropertyAssignment ? property : property.initializer, type); - } - else { - error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), declarationNameToString(name)); + const text = getTextOfPropertyName(name); + if (text) { + const prop = getPropertyOfType(objectLiteralType, text); + if (prop) { + markPropertyAsReferenced(prop, property, rightIsThis); + checkPropertyAccessibility(property, /*isSuper*/ false, objectLiteralType, prop); + } } + const exprType = getLiteralTypeFromPropertyName(name); + const elementType = getIndexedAccessType(objectLiteralType, exprType, name); + const type = getFlowTypeOfDestructuring(property, elementType); + return checkDestructuringAssignment(property.kind === SyntaxKind.ShorthandPropertyAssignment ? property : property.initializer, type); } else if (property.kind === SyntaxKind.SpreadAssignment) { if (languageVersion < ScriptTarget.ESNext) { @@ -22045,31 +22057,11 @@ namespace ts { } } - function getTypeOfObjectLiteralDestructuringProperty(objectLiteralType: Type, name: PropertyName, property: PropertyAssignment | ShorthandPropertyAssignment, rightIsThis: boolean) { - if (isTypeAny(objectLiteralType)) { - return objectLiteralType; - } - - let type: Type | undefined; - const text = getTextOfPropertyName(name); - if (text) { // TODO: GH#26379 - const prop = getPropertyOfType(objectLiteralType, text); - if (prop) { - markPropertyAsReferenced(prop, property, rightIsThis); - checkPropertyAccessibility(property, /*isSuper*/ false, objectLiteralType, prop); - type = getTypeOfSymbol(prop); - } - type = type || (isNumericLiteralName(text) ? getIndexTypeOfType(objectLiteralType, IndexKind.Number) : undefined); - } - return type || getIndexTypeOfType(objectLiteralType, IndexKind.String); - } - function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, checkMode?: CheckMode): Type { const elements = node.elements; if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { checkExternalEmitHelpers(node, ExternalEmitHelpers.Read); } - // This elementType will be used if the specific property corresponding to this index is not // present (aka the tuple element property). This call also checks that the parentType is in // fact an iterable or array (depending on target language). @@ -22086,39 +22078,30 @@ namespace ts { const element = elements[elementIndex]; if (element.kind !== SyntaxKind.OmittedExpression) { if (element.kind !== SyntaxKind.SpreadElement) { - const propName = "" + elementIndex as __String; - const type = isTypeAny(sourceType) ? sourceType : - everyType(sourceType, isTupleLikeType) ? getTupleElementType(sourceType, elementIndex) : - elementType; - if (type) { + const indexType = getLiteralType(elementIndex); + if (isArrayLikeType(sourceType)) { + // We create a synthetic expression so that getIndexedAccessType doesn't get confused + // when the element is a SyntaxKind.ElementAccessExpression. + const elementType = getIndexedAccessType(sourceType, indexType, createSyntheticExpression(element, indexType)); + const type = getFlowTypeOfDestructuring(element, elementType); return checkDestructuringAssignment(element, type, checkMode); } - // We still need to check element expression here because we may need to set appropriate flag on the expression - // such as NodeCheckFlags.LexicalThis on "this"expression. - checkExpression(element); - if (isTupleType(sourceType)) { - error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), getTypeReferenceArity(sourceType), elements.length); - } - else { - error(element, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName as string); - } + return checkDestructuringAssignment(element, elementType, checkMode); + } + if (elementIndex < elements.length - 1) { + error(element, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); } else { - if (elementIndex < elements.length - 1) { - error(element, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); + const restExpression = (element).expression; + if (restExpression.kind === SyntaxKind.BinaryExpression && (restExpression).operatorToken.kind === SyntaxKind.EqualsToken) { + error((restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer); } else { - const restExpression = (element).expression; - if (restExpression.kind === SyntaxKind.BinaryExpression && (restExpression).operatorToken.kind === SyntaxKind.EqualsToken) { - error((restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer); - } - else { - checkGrammarForDisallowedTrailingComma(node.elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); - const type = everyType(sourceType, isTupleType) ? - mapType(sourceType, t => sliceTupleType(t, elementIndex)) : - createArrayType(elementType); - return checkDestructuringAssignment(restExpression, type, checkMode); - } + checkGrammarForDisallowedTrailingComma(node.elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + const type = everyType(sourceType, isTupleType) ? + mapType(sourceType, t => sliceTupleType(t, elementIndex)) : + createArrayType(elementType); + return checkDestructuringAssignment(restExpression, type, checkMode); } } } @@ -26957,7 +26940,7 @@ namespace ts { return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText); case SyntaxKind.ElementAccessExpression: case SyntaxKind.PropertyAccessExpression: - const ex = expr; + const ex = expr; if (isConstantMemberAccess(ex)) { const type = getTypeOfExpression(ex.expression); if (type.symbol && type.symbol.flags & SymbolFlags.Enum) { @@ -28931,7 +28914,7 @@ namespace ts { return getNodeLinks(node).enumMemberValue; } - function canHaveConstantValue(node: Node): node is EnumMember | PropertyAccessExpression | ElementAccessExpression { + function canHaveConstantValue(node: Node): node is EnumMember | AccessExpression { switch (node.kind) { case SyntaxKind.EnumMember: case SyntaxKind.PropertyAccessExpression: @@ -28941,7 +28924,7 @@ namespace ts { return false; } - function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined { + function getConstantValue(node: EnumMember | AccessExpression): string | number | undefined { if (node.kind === SyntaxKind.EnumMember) { return getEnumMemberValue(node); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2cbf5784d0786..941421966149a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1636,14 +1636,6 @@ "category": "Error", "code": 2458 }, - "Type '{0}' has no property '{1}' and no string index signature.": { - "category": "Error", - "code": 2459 - }, - "Type '{0}' has no property '{1}'.": { - "category": "Error", - "code": 2460 - }, "Type '{0}' is not an array type.": { "category": "Error", "code": 2461 @@ -1760,7 +1752,7 @@ "category": "Error", "code": 2492 }, - "Tuple type '{0}' with length '{1}' cannot be assigned to tuple with length '{2}'.": { + "Tuple type '{0}' of length '{1}' has no element at index '{2}'.": { "category": "Error", "code": 2493 }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 495465f70326c..8110f8fd17a0e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1745,6 +1745,9 @@ namespace ts { export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; + /* @internal */ + export type AccessExpression = PropertyAccessExpression | ElementAccessExpression; + export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 966149f2a6c41..710ff6a671017 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4590,6 +4590,10 @@ namespace ts { || kind === SyntaxKind.JSDocFunctionType || kind === SyntaxKind.JSDocVariadicType; } + + export function isAccessExpression(node: Node): node is AccessExpression { + return node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.ElementAccessExpression; + } } namespace ts { diff --git a/tests/baselines/reference/ES5For-of31.errors.txt b/tests/baselines/reference/ES5For-of31.errors.txt index 4a49e1fdf925d..4424a870071fa 100644 --- a/tests/baselines/reference/ES5For-of31.errors.txt +++ b/tests/baselines/reference/ES5For-of31.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/statements/for-ofStatements/ES5For-of31.ts(3,8): error TS2459: Type 'undefined' has no property 'a' and no string index signature. -tests/cases/conformance/statements/for-ofStatements/ES5For-of31.ts(3,18): error TS2459: Type 'undefined' has no property 'b' and no string index signature. +tests/cases/conformance/statements/for-ofStatements/ES5For-of31.ts(3,8): error TS2339: Property 'a' does not exist on type 'undefined'. +tests/cases/conformance/statements/for-ofStatements/ES5For-of31.ts(3,18): error TS2339: Property 'b' does not exist on type 'undefined'. ==== tests/cases/conformance/statements/for-ofStatements/ES5For-of31.ts (2 errors) ==== @@ -7,9 +7,9 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-of31.ts(3,18): error for ({ a: b = 1, b: a = ""} of []) { ~ -!!! error TS2459: Type 'undefined' has no property 'a' and no string index signature. +!!! error TS2339: Property 'a' does not exist on type 'undefined'. ~ -!!! error TS2459: Type 'undefined' has no property 'b' and no string index signature. +!!! error TS2339: Property 'b' does not exist on type 'undefined'. a; b; } \ No newline at end of file diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt index 50678ea4bb39a..b34b889691923 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt +++ b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt @@ -1,7 +1,5 @@ -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,12): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(16,12): error TS2460: Type 'StrNum' has no property '2'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,12): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,5): error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,12): error TS2460: Type '{ 0: string; 1: number; length: 2; }' has no property '2'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2741: Property '2' is missing in type '[string, number]' but required in type '[number, number, number]'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(19,5): error TS2741: Property '2' is missing in type 'StrNum' but required in type '[number, number, number]'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2740: Type '{ 0: string; 1: number; length: 2; }' is missing the following properties from type '[number, number, number]': 2, pop, push, concat, and 16 more. @@ -30,7 +28,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(31,5): error tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error TS2740: Type '{ 0: string; 1: number; length: 2; }' is missing the following properties from type '[number, string]': pop, push, concat, join, and 15 more. -==== tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts (19 errors) ==== +==== tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts (17 errors) ==== interface StrNum extends Array { 0: string; 1: number; @@ -47,15 +45,11 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error var [a, b, c] = x; ~ -!!! error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. var [d, e, f] = y; - ~ -!!! error TS2460: Type 'StrNum' has no property '2'. var [g, h, i] = z; ~~~~~~~~~ !!! error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type. - ~ -!!! error TS2460: Type '{ 0: string; 1: number; length: 2; }' has no property '2'. var j1: [number, number, number] = x; ~~ !!! error TS2741: Property '2' is missing in type '[string, number]' but required in type '[number, number, number]'. diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.types b/tests/baselines/reference/arityAndOrderCompatibility01.types index d7a0923d9646e..aa658ba762934 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.types +++ b/tests/baselines/reference/arityAndOrderCompatibility01.types @@ -32,18 +32,18 @@ var z: { var [a, b, c] = x; >a : string >b : number ->c : any +>c : undefined >x : [string, number] var [d, e, f] = y; >d : string >e : number ->f : any +>f : string | number >y : StrNum var [g, h, i] = z; ->g : string ->h : number +>g : any +>h : any >i : any >z : { 0: string; 1: number; length: 2; } diff --git a/tests/baselines/reference/bestCommonTypeOfTuple.errors.txt b/tests/baselines/reference/bestCommonTypeOfTuple.errors.txt index e3c5dcc798662..0349ce1ebe451 100644 --- a/tests/baselines/reference/bestCommonTypeOfTuple.errors.txt +++ b/tests/baselines/reference/bestCommonTypeOfTuple.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(22,13): error TS2339: Property '2' does not exist on type '[(x: number) => string, (x: number) => number]'. -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(23,13): error TS2339: Property '2' does not exist on type '[E1, E2]'. -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(24,13): error TS2339: Property '2' does not exist on type '[number, any]'. -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(25,13): error TS2339: Property '3' does not exist on type '[E1, E2, number]'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(22,13): error TS2493: Tuple type '[(x: number) => string, (x: number) => number]' of length '2' has no element at index '2'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(23,13): error TS2493: Tuple type '[E1, E2]' of length '2' has no element at index '2'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(24,13): error TS2493: Tuple type '[number, any]' of length '2' has no element at index '2'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(25,13): error TS2493: Tuple type '[E1, E2, number]' of length '3' has no element at index '3'. ==== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts (4 errors) ==== @@ -28,13 +28,13 @@ tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfT t4 = [E1.one, E2.two, 20]; var e1 = t1[2]; // {} ~ -!!! error TS2339: Property '2' does not exist on type '[(x: number) => string, (x: number) => number]'. +!!! error TS2493: Tuple type '[(x: number) => string, (x: number) => number]' of length '2' has no element at index '2'. var e2 = t2[2]; // {} ~ -!!! error TS2339: Property '2' does not exist on type '[E1, E2]'. +!!! error TS2493: Tuple type '[E1, E2]' of length '2' has no element at index '2'. var e3 = t3[2]; // any ~ -!!! error TS2339: Property '2' does not exist on type '[number, any]'. +!!! error TS2493: Tuple type '[number, any]' of length '2' has no element at index '2'. var e4 = t4[3]; // number ~ -!!! error TS2339: Property '3' does not exist on type '[E1, E2, number]'. \ No newline at end of file +!!! error TS2493: Tuple type '[E1, E2, number]' of length '3' has no element at index '3'. \ No newline at end of file diff --git a/tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt b/tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt index d2fd301e13181..602e9fdeef212 100644 --- a/tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt +++ b/tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(17,14): error TS2339: Property '4' does not exist on type '[C, base]'. -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(18,14): error TS2339: Property '4' does not exist on type '[C, D]'. -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(19,14): error TS2339: Property '4' does not exist on type '[C1, D1]'. -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(20,14): error TS2339: Property '2' does not exist on type '[base1, C1]'. -tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(21,14): error TS2339: Property '2' does not exist on type '[C1, F]'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(17,14): error TS2493: Tuple type '[C, base]' of length '2' has no element at index '4'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(18,14): error TS2493: Tuple type '[C, D]' of length '2' has no element at index '4'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(19,14): error TS2493: Tuple type '[C1, D1]' of length '2' has no element at index '4'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(20,14): error TS2493: Tuple type '[base1, C1]' of length '2' has no element at index '2'. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(21,14): error TS2493: Tuple type '[C1, F]' of length '2' has no element at index '2'. ==== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts (5 errors) ==== @@ -24,17 +24,17 @@ tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfT var e11 = t1[4]; // base ~ -!!! error TS2339: Property '4' does not exist on type '[C, base]'. +!!! error TS2493: Tuple type '[C, base]' of length '2' has no element at index '4'. var e21 = t2[4]; // {} ~ -!!! error TS2339: Property '4' does not exist on type '[C, D]'. +!!! error TS2493: Tuple type '[C, D]' of length '2' has no element at index '4'. var e31 = t3[4]; // C1 ~ -!!! error TS2339: Property '4' does not exist on type '[C1, D1]'. +!!! error TS2493: Tuple type '[C1, D1]' of length '2' has no element at index '4'. var e41 = t4[2]; // base1 ~ -!!! error TS2339: Property '2' does not exist on type '[base1, C1]'. +!!! error TS2493: Tuple type '[base1, C1]' of length '2' has no element at index '2'. var e51 = t5[2]; // {} ~ -!!! error TS2339: Property '2' does not exist on type '[C1, F]'. +!!! error TS2493: Tuple type '[C1, F]' of length '2' has no element at index '2'. \ No newline at end of file diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt index 4587612cb7648..4ddb42ed2d91d 100644 --- a/tests/baselines/reference/castingTuple.errors.txt +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -6,7 +6,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Conver tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Conversion of type '[C, D]' to type '[C, D, A]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property '2' is missing in type '[C, D]' but required in type '[C, D, A]'. -tests/cases/conformance/types/tuple/castingTuple.ts(20,33): error TS2339: Property '5' does not exist on type '[C, D, A]'. +tests/cases/conformance/types/tuple/castingTuple.ts(20,33): error TS2493: Tuple type '[C, D, A]' of length '3' has no element at index '5'. tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type 'string' is not comparable to type 'number'. tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Conversion of type '[C, D]' to type '[A, I]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. @@ -49,7 +49,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot var eleFromCDA1 = classCDATuple[2]; // A var eleFromCDA2 = classCDATuple[5]; // C | D | A ~ -!!! error TS2339: Property '5' does not exist on type '[C, D, A]'. +!!! error TS2493: Tuple type '[C, D, A]' of length '3' has no element at index '5'. var t10: [E1, E2] = [E1.one, E2.one]; var t11 = <[number, number]>t10; var array1 = <{}[]>emptyObjTuple; diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt b/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt index 31b938fb3fb3e..dc71d916a36fa 100644 --- a/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt +++ b/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt @@ -10,11 +10,17 @@ tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,8): error TS2349: tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,8): error TS2538: Type 'any' cannot be used as an index type. tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,8): error TS2538: Type 'any' cannot be used as an index type. tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,12): error TS2339: Property 'toExponential' does not exist on type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(24,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(28,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(30,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(31,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. tests/cases/compiler/computedPropertiesInDestructuring1.ts(33,4): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(33,4): error TS2538: Type 'any' cannot be used as an index type. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,4): error TS2538: Type 'any' cannot be used as an index type. tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,5): error TS2365: Operator '+' cannot be applied to types '1' and '{}'. -==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (14 errors) ==== +==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (20 errors) ==== // destructuring in variable declarations let foo = "bar"; let {[foo]: bar} = {bar: "bar"}; @@ -63,18 +69,30 @@ tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,5): error TS2365: // destructuring assignment ({[foo]: bar} = {bar: "bar"}); + ~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. ({["bar"]: bar2} = {bar: "bar"}); ({[foo2()]: bar3} = {bar: "bar"}); + ~~~~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. [{[foo]: bar4}] = [{bar: "bar"}]; + ~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. [{[foo2()]: bar5}] = [{bar: "bar"}]; + ~~~~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. [{[foo()]: bar4}] = [{bar: "bar"}]; ~~~~~ !!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. + ~~~~~ +!!! error TS2538: Type 'any' cannot be used as an index type. [{[(1 + {})]: bar4}] = [{bar: "bar"}]; + ~~~~~~~~ +!!! error TS2538: Type 'any' cannot be used as an index type. ~~~~~~ !!! error TS2365: Operator '+' cannot be applied to types '1' and '{}'. diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt index 610b8e56ab3da..b839a20974346 100644 --- a/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt @@ -10,11 +10,17 @@ tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,8): error TS23 tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,8): error TS2538: Type 'any' cannot be used as an index type. tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,8): error TS2538: Type 'any' cannot be used as an index type. tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,12): error TS2339: Property 'toExponential' does not exist on type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(25,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(29,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(31,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(32,4): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(34,4): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(34,4): error TS2538: Type 'any' cannot be used as an index type. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,4): error TS2538: Type 'any' cannot be used as an index type. tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,5): error TS2365: Operator '+' cannot be applied to types '1' and '{}'. -==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (14 errors) ==== +==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (20 errors) ==== // destructuring in variable declarations let foo = "bar"; let {[foo]: bar} = {bar: "bar"}; @@ -64,18 +70,30 @@ tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,5): error TS23 // destructuring assignment ({[foo]: bar} = {bar: "bar"}); + ~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. ({["bar"]: bar2} = {bar: "bar"}); ({[foo2()]: bar3} = {bar: "bar"}); + ~~~~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. [{[foo]: bar4}] = [{bar: "bar"}]; + ~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. [{[foo2()]: bar5}] = [{bar: "bar"}]; + ~~~~~~ +!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'. [{[foo()]: bar4}] = [{bar: "bar"}]; ~~~~~ !!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. + ~~~~~ +!!! error TS2538: Type 'any' cannot be used as an index type. [{[(1 + {})]: bar4}] = [{bar: "bar"}]; + ~~~~~~~~ +!!! error TS2538: Type 'any' cannot be used as an index type. ~~~~~~ !!! error TS2365: Operator '+' cannot be applied to types '1' and '{}'. \ No newline at end of file diff --git a/tests/baselines/reference/declarationsAndAssignments.types b/tests/baselines/reference/declarationsAndAssignments.types index edb00c9879b0d..89ddd0eb5e5fc 100644 --- a/tests/baselines/reference/declarationsAndAssignments.types +++ b/tests/baselines/reference/declarationsAndAssignments.types @@ -277,8 +277,8 @@ function f9() { >{} : {} var [c, d] = { 0: 10, 1: 20 }; // Error, not array type ->c : number ->d : number +>c : any +>d : any >{ 0: 10, 1: 20 } : { 0: number; 1: number; } >0 : number >10 : 10 diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types index aa4f3a73b098f..77681f8d8c840 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types @@ -42,7 +42,7 @@ var [b3 = "string", b4, b5] = bar(); // Error >b3 : string | Number >"string" : "string" >b4 : Number ->b5 : Number +>b5 : number >bar() : J >bar : () => J diff --git a/tests/baselines/reference/destructuringControlFlow.errors.txt b/tests/baselines/reference/destructuringControlFlow.errors.txt new file mode 100644 index 0000000000000..2bc85fdd638e3 --- /dev/null +++ b/tests/baselines/reference/destructuringControlFlow.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts(31,8): error TS2339: Property 'x' does not exist on type 'Number'. +tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts(32,9): error TS2339: Property 'x' does not exist on type 'Number'. +tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts(33,9): error TS2537: Type 'Number' has no matching index signature for type 'string'. + + +==== tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts (3 errors) ==== + function f1(obj: { a?: string }) { + if (obj.a) { + obj = {}; + let a1 = obj["a"]; // string | undefined + let a2 = obj.a; // string | undefined + } + } + + function f2(obj: [number, string] | null[]) { + let a0 = obj[0]; // number | null + let a1 = obj[1]; // string | null + let [b0, b1] = obj; + ([a0, a1] = obj); + if (obj[0] && obj[1]) { + let c0 = obj[0]; // number + let c1 = obj[1]; // string + let [d0, d1] = obj; + ([c0, c1] = obj); + } + } + + function f3(obj: { a?: number, b?: string }) { + if (obj.a && obj.b) { + let { a, b } = obj; // number, string + ({ a, b } = obj); + } + } + + function f4() { + let x: boolean; + ({ x } = 0); // Error + ~ +!!! error TS2339: Property 'x' does not exist on type 'Number'. + ({ ["x"]: x } = 0); // Error + ~~~ +!!! error TS2339: Property 'x' does not exist on type 'Number'. + ({ ["x" + ""]: x } = 0); // Errpr + ~~~~~~~~ +!!! error TS2537: Type 'Number' has no matching index signature for type 'string'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringControlFlow.js b/tests/baselines/reference/destructuringControlFlow.js new file mode 100644 index 0000000000000..2d02fb5a40f4a --- /dev/null +++ b/tests/baselines/reference/destructuringControlFlow.js @@ -0,0 +1,71 @@ +//// [destructuringControlFlow.ts] +function f1(obj: { a?: string }) { + if (obj.a) { + obj = {}; + let a1 = obj["a"]; // string | undefined + let a2 = obj.a; // string | undefined + } +} + +function f2(obj: [number, string] | null[]) { + let a0 = obj[0]; // number | null + let a1 = obj[1]; // string | null + let [b0, b1] = obj; + ([a0, a1] = obj); + if (obj[0] && obj[1]) { + let c0 = obj[0]; // number + let c1 = obj[1]; // string + let [d0, d1] = obj; + ([c0, c1] = obj); + } +} + +function f3(obj: { a?: number, b?: string }) { + if (obj.a && obj.b) { + let { a, b } = obj; // number, string + ({ a, b } = obj); + } +} + +function f4() { + let x: boolean; + ({ x } = 0); // Error + ({ ["x"]: x } = 0); // Error + ({ ["x" + ""]: x } = 0); // Errpr +} + + +//// [destructuringControlFlow.js] +"use strict"; +function f1(obj) { + if (obj.a) { + obj = {}; + var a1 = obj["a"]; // string | undefined + var a2 = obj.a; // string | undefined + } +} +function f2(obj) { + var a0 = obj[0]; // number | null + var a1 = obj[1]; // string | null + var b0 = obj[0], b1 = obj[1]; + (a0 = obj[0], a1 = obj[1]); + if (obj[0] && obj[1]) { + var c0 = obj[0]; // number + var c1 = obj[1]; // string + var d0 = obj[0], d1 = obj[1]; + (c0 = obj[0], c1 = obj[1]); + } +} +function f3(obj) { + if (obj.a && obj.b) { + var a = obj.a, b = obj.b; // number, string + (a = obj.a, b = obj.b); + } +} +function f4() { + var _a; + var x; + (x = 0..x); // Error + (x = 0["x"]); // Error + (_a = "x" + "", x = 0[_a]); // Errpr +} diff --git a/tests/baselines/reference/destructuringControlFlow.symbols b/tests/baselines/reference/destructuringControlFlow.symbols new file mode 100644 index 0000000000000..75cbfcdb481b7 --- /dev/null +++ b/tests/baselines/reference/destructuringControlFlow.symbols @@ -0,0 +1,124 @@ +=== tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts === +function f1(obj: { a?: string }) { +>f1 : Symbol(f1, Decl(destructuringControlFlow.ts, 0, 0)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 0, 12)) +>a : Symbol(a, Decl(destructuringControlFlow.ts, 0, 18)) + + if (obj.a) { +>obj.a : Symbol(a, Decl(destructuringControlFlow.ts, 0, 18)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 0, 12)) +>a : Symbol(a, Decl(destructuringControlFlow.ts, 0, 18)) + + obj = {}; +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 0, 12)) + + let a1 = obj["a"]; // string | undefined +>a1 : Symbol(a1, Decl(destructuringControlFlow.ts, 3, 11)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 0, 12)) +>"a" : Symbol(a, Decl(destructuringControlFlow.ts, 0, 18)) + + let a2 = obj.a; // string | undefined +>a2 : Symbol(a2, Decl(destructuringControlFlow.ts, 4, 11)) +>obj.a : Symbol(a, Decl(destructuringControlFlow.ts, 0, 18)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 0, 12)) +>a : Symbol(a, Decl(destructuringControlFlow.ts, 0, 18)) + } +} + +function f2(obj: [number, string] | null[]) { +>f2 : Symbol(f2, Decl(destructuringControlFlow.ts, 6, 1)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) + + let a0 = obj[0]; // number | null +>a0 : Symbol(a0, Decl(destructuringControlFlow.ts, 9, 7)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) +>0 : Symbol(0) + + let a1 = obj[1]; // string | null +>a1 : Symbol(a1, Decl(destructuringControlFlow.ts, 10, 7)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) +>1 : Symbol(1) + + let [b0, b1] = obj; +>b0 : Symbol(b0, Decl(destructuringControlFlow.ts, 11, 9)) +>b1 : Symbol(b1, Decl(destructuringControlFlow.ts, 11, 12)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) + + ([a0, a1] = obj); +>a0 : Symbol(a0, Decl(destructuringControlFlow.ts, 9, 7)) +>a1 : Symbol(a1, Decl(destructuringControlFlow.ts, 10, 7)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) + + if (obj[0] && obj[1]) { +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) +>0 : Symbol(0) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) +>1 : Symbol(1) + + let c0 = obj[0]; // number +>c0 : Symbol(c0, Decl(destructuringControlFlow.ts, 14, 11)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) +>0 : Symbol(0) + + let c1 = obj[1]; // string +>c1 : Symbol(c1, Decl(destructuringControlFlow.ts, 15, 11)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) +>1 : Symbol(1) + + let [d0, d1] = obj; +>d0 : Symbol(d0, Decl(destructuringControlFlow.ts, 16, 13)) +>d1 : Symbol(d1, Decl(destructuringControlFlow.ts, 16, 16)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) + + ([c0, c1] = obj); +>c0 : Symbol(c0, Decl(destructuringControlFlow.ts, 14, 11)) +>c1 : Symbol(c1, Decl(destructuringControlFlow.ts, 15, 11)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 8, 12)) + } +} + +function f3(obj: { a?: number, b?: string }) { +>f3 : Symbol(f3, Decl(destructuringControlFlow.ts, 19, 1)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 21, 12)) +>a : Symbol(a, Decl(destructuringControlFlow.ts, 21, 18)) +>b : Symbol(b, Decl(destructuringControlFlow.ts, 21, 30)) + + if (obj.a && obj.b) { +>obj.a : Symbol(a, Decl(destructuringControlFlow.ts, 21, 18)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 21, 12)) +>a : Symbol(a, Decl(destructuringControlFlow.ts, 21, 18)) +>obj.b : Symbol(b, Decl(destructuringControlFlow.ts, 21, 30)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 21, 12)) +>b : Symbol(b, Decl(destructuringControlFlow.ts, 21, 30)) + + let { a, b } = obj; // number, string +>a : Symbol(a, Decl(destructuringControlFlow.ts, 23, 13)) +>b : Symbol(b, Decl(destructuringControlFlow.ts, 23, 16)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 21, 12)) + + ({ a, b } = obj); +>a : Symbol(a, Decl(destructuringControlFlow.ts, 24, 10)) +>b : Symbol(b, Decl(destructuringControlFlow.ts, 24, 13)) +>obj : Symbol(obj, Decl(destructuringControlFlow.ts, 21, 12)) + } +} + +function f4() { +>f4 : Symbol(f4, Decl(destructuringControlFlow.ts, 26, 1)) + + let x: boolean; +>x : Symbol(x, Decl(destructuringControlFlow.ts, 29, 7)) + + ({ x } = 0); // Error +>x : Symbol(x, Decl(destructuringControlFlow.ts, 30, 6)) + + ({ ["x"]: x } = 0); // Error +>["x"] : Symbol(["x"], Decl(destructuringControlFlow.ts, 31, 6)) +>"x" : Symbol(["x"], Decl(destructuringControlFlow.ts, 31, 6)) +>x : Symbol(x, Decl(destructuringControlFlow.ts, 29, 7)) + + ({ ["x" + ""]: x } = 0); // Errpr +>["x" + ""] : Symbol(["x" + ""], Decl(destructuringControlFlow.ts, 32, 6)) +>x : Symbol(x, Decl(destructuringControlFlow.ts, 29, 7)) +} + diff --git a/tests/baselines/reference/destructuringControlFlow.types b/tests/baselines/reference/destructuringControlFlow.types new file mode 100644 index 0000000000000..b831d1167408e --- /dev/null +++ b/tests/baselines/reference/destructuringControlFlow.types @@ -0,0 +1,160 @@ +=== tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts === +function f1(obj: { a?: string }) { +>f1 : (obj: { a?: string | undefined; }) => void +>obj : { a?: string | undefined; } +>a : string | undefined + + if (obj.a) { +>obj.a : string | undefined +>obj : { a?: string | undefined; } +>a : string | undefined + + obj = {}; +>obj = {} : {} +>obj : { a?: string | undefined; } +>{} : {} + + let a1 = obj["a"]; // string | undefined +>a1 : string | undefined +>obj["a"] : string | undefined +>obj : { a?: string | undefined; } +>"a" : "a" + + let a2 = obj.a; // string | undefined +>a2 : string | undefined +>obj.a : string | undefined +>obj : { a?: string | undefined; } +>a : string | undefined + } +} + +function f2(obj: [number, string] | null[]) { +>f2 : (obj: [number, string] | null[]) => void +>obj : [number, string] | null[] +>null : null + + let a0 = obj[0]; // number | null +>a0 : number | null +>obj[0] : number | null +>obj : [number, string] | null[] +>0 : 0 + + let a1 = obj[1]; // string | null +>a1 : string | null +>obj[1] : string | null +>obj : [number, string] | null[] +>1 : 1 + + let [b0, b1] = obj; +>b0 : number | null +>b1 : string | null +>obj : [number, string] | null[] + + ([a0, a1] = obj); +>([a0, a1] = obj) : [number, string] | null[] +>[a0, a1] = obj : [number, string] | null[] +>[a0, a1] : [number | null, string | null] +>a0 : number | null +>a1 : string | null +>obj : [number, string] | null[] + + if (obj[0] && obj[1]) { +>obj[0] && obj[1] : string | 0 | null +>obj[0] : number | null +>obj : [number, string] | null[] +>0 : 0 +>obj[1] : string | null +>obj : [number, string] | null[] +>1 : 1 + + let c0 = obj[0]; // number +>c0 : number +>obj[0] : number +>obj : [number, string] | null[] +>0 : 0 + + let c1 = obj[1]; // string +>c1 : string +>obj[1] : string +>obj : [number, string] | null[] +>1 : 1 + + let [d0, d1] = obj; +>d0 : number +>d1 : string +>obj : [number, string] | null[] + + ([c0, c1] = obj); +>([c0, c1] = obj) : [number, string] | null[] +>[c0, c1] = obj : [number, string] | null[] +>[c0, c1] : [number, string] +>c0 : number +>c1 : string +>obj : [number, string] | null[] + } +} + +function f3(obj: { a?: number, b?: string }) { +>f3 : (obj: { a?: number | undefined; b?: string | undefined; }) => void +>obj : { a?: number | undefined; b?: string | undefined; } +>a : number | undefined +>b : string | undefined + + if (obj.a && obj.b) { +>obj.a && obj.b : string | 0 | undefined +>obj.a : number | undefined +>obj : { a?: number | undefined; b?: string | undefined; } +>a : number | undefined +>obj.b : string | undefined +>obj : { a?: number | undefined; b?: string | undefined; } +>b : string | undefined + + let { a, b } = obj; // number, string +>a : number +>b : string +>obj : { a?: number | undefined; b?: string | undefined; } + + ({ a, b } = obj); +>({ a, b } = obj) : { a?: number | undefined; b?: string | undefined; } +>{ a, b } = obj : { a?: number | undefined; b?: string | undefined; } +>{ a, b } : { a: number; b: string; } +>a : number +>b : string +>obj : { a?: number | undefined; b?: string | undefined; } + } +} + +function f4() { +>f4 : () => void + + let x: boolean; +>x : boolean + + ({ x } = 0); // Error +>({ x } = 0) : 0 +>{ x } = 0 : 0 +>{ x } : { x: boolean; } +>x : boolean +>0 : 0 + + ({ ["x"]: x } = 0); // Error +>({ ["x"]: x } = 0) : 0 +>{ ["x"]: x } = 0 : 0 +>{ ["x"]: x } : { ["x"]: boolean; } +>["x"] : boolean +>"x" : "x" +>x : boolean +>0 : 0 + + ({ ["x" + ""]: x } = 0); // Errpr +>({ ["x" + ""]: x } = 0) : 0 +>{ ["x" + ""]: x } = 0 : 0 +>{ ["x" + ""]: x } : { [x: string]: boolean; } +>["x" + ""] : boolean +>"x" + "" : string +>"x" : "x" +>"" : "" +>x : boolean +>0 : 0 +} + diff --git a/tests/baselines/reference/emitCapturingThisInTupleDestructuring1.errors.txt b/tests/baselines/reference/emitCapturingThisInTupleDestructuring1.errors.txt index d0f11d056ca53..5b8f2346ee99c 100644 --- a/tests/baselines/reference/emitCapturingThisInTupleDestructuring1.errors.txt +++ b/tests/baselines/reference/emitCapturingThisInTupleDestructuring1.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/emitCapturingThisInTupleDestructuring1.ts(3,17): error TS2493: Tuple type '[any]' with length '1' cannot be assigned to tuple with length '3'. -tests/cases/compiler/emitCapturingThisInTupleDestructuring1.ts(3,29): error TS2493: Tuple type '[any]' with length '1' cannot be assigned to tuple with length '3'. +tests/cases/compiler/emitCapturingThisInTupleDestructuring1.ts(3,17): error TS2493: Tuple type '[any]' of length '1' has no element at index '1'. +tests/cases/compiler/emitCapturingThisInTupleDestructuring1.ts(3,29): error TS2493: Tuple type '[any]' of length '1' has no element at index '2'. ==== tests/cases/compiler/emitCapturingThisInTupleDestructuring1.ts (2 errors) ==== @@ -7,7 +7,7 @@ tests/cases/compiler/emitCapturingThisInTupleDestructuring1.ts(3,29): error TS24 wrapper((array: [any]) => { [this.test, this.test1, this.test2] = array; // even though there is a compiler error, we should still emit lexical capture for "this" ~~~~~~~~~~ -!!! error TS2493: Tuple type '[any]' with length '1' cannot be assigned to tuple with length '3'. +!!! error TS2493: Tuple type '[any]' of length '1' has no element at index '1'. ~~~~~~~~~~ -!!! error TS2493: Tuple type '[any]' with length '1' cannot be assigned to tuple with length '3'. +!!! error TS2493: Tuple type '[any]' of length '1' has no element at index '2'. }); \ No newline at end of file diff --git a/tests/baselines/reference/emitCapturingThisInTupleDestructuring2.errors.txt b/tests/baselines/reference/emitCapturingThisInTupleDestructuring2.errors.txt index 25207e28c79a9..5d14e2401c49e 100644 --- a/tests/baselines/reference/emitCapturingThisInTupleDestructuring2.errors.txt +++ b/tests/baselines/reference/emitCapturingThisInTupleDestructuring2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/emitCapturingThisInTupleDestructuring2.ts(8,39): error TS2493: Tuple type '[number, number]' with length '2' cannot be assigned to tuple with length '3'. +tests/cases/compiler/emitCapturingThisInTupleDestructuring2.ts(8,39): error TS2493: Tuple type '[number, number]' of length '2' has no element at index '2'. ==== tests/cases/compiler/emitCapturingThisInTupleDestructuring2.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/compiler/emitCapturingThisInTupleDestructuring2.ts(8,39): error TS24 method() { () => [this.test, this.test1, this.test2] = array1; // even though there is a compiler error, we should still emit lexical capture for "this" ~~~~~~~~~~ -!!! error TS2493: Tuple type '[number, number]' with length '2' cannot be assigned to tuple with length '3'. +!!! error TS2493: Tuple type '[number, number]' of length '2' has no element at index '2'. } } \ No newline at end of file diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt b/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt index e3b857412cc49..f1c4d76fe2b45 100644 --- a/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt +++ b/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts(2,11): error TS2339: Property '0' does not exist on type '[]'. +tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts(2,11): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts (1 errors) ==== let x = <[]>[]; let y = x[0]; ~ -!!! error TS2339: Property '0' does not exist on type '[]'. \ No newline at end of file +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. \ No newline at end of file diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt b/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt index 34d22dc673a34..64663106a1e07 100644 --- a/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt +++ b/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts(2,11): error TS2339: Property '0' does not exist on type '[]'. +tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts(2,11): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts (1 errors) ==== let x = [] as []; let y = x[0]; ~ -!!! error TS2339: Property '0' does not exist on type '[]'. \ No newline at end of file +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithTupleType.errors.txt b/tests/baselines/reference/genericCallWithTupleType.errors.txt index ec3c40ccad984..0cc4a4986db31 100644 --- a/tests/baselines/reference/genericCallWithTupleType.errors.txt +++ b/tests/baselines/reference/genericCallWithTupleType.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(12,1): error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'. Types of property 'length' are incompatible. Type '4' is not assignable to type '2'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(13,20): error TS2339: Property '2' does not exist on type '[string, number]'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(13,20): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,1): error TS2322: Type '{ a: string; }' is not assignable to type 'undefined'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,11): error TS2339: Property '3' does not exist on type '[string, number]'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(15,20): error TS2339: Property '3' does not exist on type '[string, number]'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,11): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '3'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(15,20): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '3'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,14): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,17): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(23,14): error TS2322: Type '{}' is not assignable to type 'string'. @@ -31,15 +31,15 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup !!! error TS2322: Type '4' is not assignable to type '2'. var e3 = i1.tuple1[2]; // {} ~ -!!! error TS2339: Property '2' does not exist on type '[string, number]'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. i1.tuple1[3] = { a: "string" }; ~~~~~~~~~~~~ !!! error TS2322: Type '{ a: string; }' is not assignable to type 'undefined'. ~ -!!! error TS2339: Property '3' does not exist on type '[string, number]'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '3'. var e4 = i1.tuple1[3]; // {} ~ -!!! error TS2339: Property '3' does not exist on type '[string, number]'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '3'. i2.tuple1 = ["foo", 5]; i2.tuple1 = ["foo", "bar"]; i2.tuple1 = [5, "bar"]; diff --git a/tests/baselines/reference/indexerWithTuple.errors.txt b/tests/baselines/reference/indexerWithTuple.errors.txt index 45cddd9313f3e..b5b09be4c4959 100644 --- a/tests/baselines/reference/indexerWithTuple.errors.txt +++ b/tests/baselines/reference/indexerWithTuple.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/types/tuple/indexerWithTuple.ts(11,25): error TS2339: Property '2' does not exist on type '[string, number]'. -tests/cases/conformance/types/tuple/indexerWithTuple.ts(17,27): error TS2339: Property '2' does not exist on type '[number, [string, number]]'. -tests/cases/conformance/types/tuple/indexerWithTuple.ts(20,30): error TS2339: Property '2' does not exist on type '[number, string | number]'. -tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2339: Property '2' does not exist on type '[boolean, string | number]'. +tests/cases/conformance/types/tuple/indexerWithTuple.ts(11,25): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. +tests/cases/conformance/types/tuple/indexerWithTuple.ts(17,27): error TS2493: Tuple type '[number, [string, number]]' of length '2' has no element at index '2'. +tests/cases/conformance/types/tuple/indexerWithTuple.ts(20,30): error TS2493: Tuple type '[number, string | number]' of length '2' has no element at index '2'. +tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2493: Tuple type '[boolean, string | number]' of length '2' has no element at index '2'. ==== tests/cases/conformance/types/tuple/indexerWithTuple.ts (4 errors) ==== @@ -17,7 +17,7 @@ tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2339: Pr var ele11 = strNumTuple[1]; // number var ele12 = strNumTuple[2]; // string | number ~ -!!! error TS2339: Property '2' does not exist on type '[string, number]'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. var ele13 = strNumTuple[idx0]; // string | number var ele14 = strNumTuple[idx1]; // string | number var ele15 = strNumTuple["0"]; // string @@ -25,12 +25,12 @@ tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2339: Pr var strNumTuple1 = numTupleTuple[1]; //[string, number]; var ele17 = numTupleTuple[2]; // number | [string, number] ~ -!!! error TS2339: Property '2' does not exist on type '[number, [string, number]]'. +!!! error TS2493: Tuple type '[number, [string, number]]' of length '2' has no element at index '2'. var eleUnion10 = unionTuple1[0]; // number var eleUnion11 = unionTuple1[1]; // string | number var eleUnion12 = unionTuple1[2]; // string | number ~ -!!! error TS2339: Property '2' does not exist on type '[number, string | number]'. +!!! error TS2493: Tuple type '[number, string | number]' of length '2' has no element at index '2'. var eleUnion13 = unionTuple1[idx0]; // string | number var eleUnion14 = unionTuple1[idx1]; // string | number var eleUnion15 = unionTuple1["0"]; // number @@ -40,7 +40,7 @@ tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2339: Pr var eleUnion21 = unionTuple2[1]; // string | number var eleUnion22 = unionTuple2[2]; // string | number | boolean ~ -!!! error TS2339: Property '2' does not exist on type '[boolean, string | number]'. +!!! error TS2493: Tuple type '[boolean, string | number]' of length '2' has no element at index '2'. var eleUnion23 = unionTuple2[idx0]; // string | number | boolean var eleUnion24 = unionTuple2[idx1]; // string | number | boolean var eleUnion25 = unionTuple2["0"]; // boolean diff --git a/tests/baselines/reference/iterableArrayPattern21.types b/tests/baselines/reference/iterableArrayPattern21.types index aefaec14194d0..beaa3c48d9d78 100644 --- a/tests/baselines/reference/iterableArrayPattern21.types +++ b/tests/baselines/reference/iterableArrayPattern21.types @@ -1,7 +1,7 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern21.ts === var [a, b] = { 0: "", 1: true }; ->a : string ->b : boolean +>a : any +>b : any >{ 0: "", 1: true } : { 0: string; 1: boolean; } >0 : string >"" : "" diff --git a/tests/baselines/reference/objectRest.errors.txt b/tests/baselines/reference/objectRest.errors.txt index 0bbd4b2f84d13..02f64fbd4e21b 100644 --- a/tests/baselines/reference/objectRest.errors.txt +++ b/tests/baselines/reference/objectRest.errors.txt @@ -3,10 +3,12 @@ tests/cases/conformance/types/rest/objectRest.ts(7,20): error TS2339: Property ' tests/cases/conformance/types/rest/objectRest.ts(43,8): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. tests/cases/conformance/types/rest/objectRest.ts(43,35): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. tests/cases/conformance/types/rest/objectRest.ts(43,57): error TS2403: Subsequent variable declarations must have the same type. Variable 'o' must be of type '{ a: number; b: string; }', but here has type '{}'. +tests/cases/conformance/types/rest/objectRest.ts(44,5): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. +tests/cases/conformance/types/rest/objectRest.ts(44,32): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. tests/cases/conformance/types/rest/objectRest.ts(44,53): error TS2739: Type '{}' is missing the following properties from type '{ a: number; b: string; }': a, b -==== tests/cases/conformance/types/rest/objectRest.ts (6 errors) ==== +==== tests/cases/conformance/types/rest/objectRest.ts (8 errors) ==== var o = { a: 1, b: 'no' } var { ...clone } = o; var { a, ...justB } = o; @@ -61,6 +63,10 @@ tests/cases/conformance/types/rest/objectRest.ts(44,53): error TS2739: Type '{}' ~ !!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o' must be of type '{ a: number; b: string; }', but here has type '{}'. ({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); + ~~~~~~~~ +!!! error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. + ~~~~~~~~~ +!!! error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. ~ !!! error TS2739: Type '{}' is missing the following properties from type '{ a: number; b: string; }': a, b diff --git a/tests/baselines/reference/restElementWithAssignmentPattern2.errors.txt b/tests/baselines/reference/restElementWithAssignmentPattern2.errors.txt index f9b11b5694cab..595e047e4e809 100644 --- a/tests/baselines/reference/restElementWithAssignmentPattern2.errors.txt +++ b/tests/baselines/reference/restElementWithAssignmentPattern2.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern2.ts(2,10): error TS2322: Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern2.ts(2,18): error TS2459: Type '(string | number)[]' has no property 'b' and no string index signature. +tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern2.ts(2,18): error TS2339: Property 'b' does not exist on type '(string | number)[]'. ==== tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern2.ts (2 errors) ==== @@ -10,4 +10,4 @@ tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern2.ts(2 !!! error TS2322: Type 'string | number' is not assignable to type 'string'. !!! error TS2322: Type 'number' is not assignable to type 'string'. ~ -!!! error TS2459: Type '(string | number)[]' has no property 'b' and no string index signature. \ No newline at end of file +!!! error TS2339: Property 'b' does not exist on type '(string | number)[]'. \ No newline at end of file diff --git a/tests/baselines/reference/restElementWithAssignmentPattern4.errors.txt b/tests/baselines/reference/restElementWithAssignmentPattern4.errors.txt index f455d3fc04a09..5a4636cf12cc1 100644 --- a/tests/baselines/reference/restElementWithAssignmentPattern4.errors.txt +++ b/tests/baselines/reference/restElementWithAssignmentPattern4.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern4.ts(3,18): error TS2459: Type '[string, number]' has no property 'b' and no string index signature. +tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern4.ts(3,18): error TS2339: Property 'b' does not exist on type '[string, number]'. ==== tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern4.ts (1 errors) ==== @@ -6,4 +6,4 @@ tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern4.ts(3 var tuple: [string, number] = ["", 1]; [...{ 0: a = "", b }] = tuple; ~ -!!! error TS2459: Type '[string, number]' has no property 'b' and no string index signature. \ No newline at end of file +!!! error TS2339: Property 'b' does not exist on type '[string, number]'. \ No newline at end of file diff --git a/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring.errors.txt b/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring.errors.txt index 67ecf2085616d..7d2ebd38c3581 100644 --- a/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring.errors.txt +++ b/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(14,9): error TS2459: Type '{}' has no property 's1' and no string index signature. -tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(20,9): error TS2459: Type '{}' has no property 's1' and no string index signature. +tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(14,9): error TS2339: Property 's1' does not exist on type '{}'. +tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(20,9): error TS2339: Property 's1' does not exist on type '{}'. tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(38,9): error TS2322: Type '5' is not assignable to type 'string'. tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(44,12): error TS2322: Type '5' is not assignable to type 'string'. tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(70,5): error TS2322: Type '5' is not assignable to type 'string'. @@ -33,7 +33,7 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(111,14): err var s1; for ({ s1 = 5 } of [{}]) { ~~ -!!! error TS2459: Type '{}' has no property 's1' and no string index signature. +!!! error TS2339: Property 's1' does not exist on type '{}'. } }); @@ -41,7 +41,7 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(111,14): err var s1; for ({ s1:s1 = 5 } of [{}]) { ~~ -!!! error TS2459: Type '{}' has no property 's1' and no string index signature. +!!! error TS2339: Property 's1' does not exist on type '{}'. } }); diff --git a/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring_ES6.errors.txt b/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring_ES6.errors.txt index c5937c9d6c47e..fa821aa51b6b8 100644 --- a/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring_ES6.errors.txt +++ b/tests/baselines/reference/shorthandPropertyAssignmentsInDestructuring_ES6.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(14,9): error TS2459: Type '{}' has no property 's1' and no string index signature. -tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(20,9): error TS2459: Type '{}' has no property 's1' and no string index signature. +tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(14,9): error TS2339: Property 's1' does not exist on type '{}'. +tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(20,9): error TS2339: Property 's1' does not exist on type '{}'. tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(38,9): error TS2322: Type '5' is not assignable to type 'string'. tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(44,12): error TS2322: Type '5' is not assignable to type 'string'. tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(70,5): error TS2322: Type '5' is not assignable to type 'string'. @@ -33,7 +33,7 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(111,14): var s1; for ({ s1 = 5 } of [{}]) { ~~ -!!! error TS2459: Type '{}' has no property 's1' and no string index signature. +!!! error TS2339: Property 's1' does not exist on type '{}'. } }); @@ -41,7 +41,7 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(111,14): var s1; for ({ s1:s1 = 5 } of [{}]) { ~~ -!!! error TS2459: Type '{}' has no property 's1' and no string index signature. +!!! error TS2339: Property 's1' does not exist on type '{}'. } }); diff --git a/tests/baselines/reference/tupleLengthCheck.errors.txt b/tests/baselines/reference/tupleLengthCheck.errors.txt index 1c6fe90913549..0612746039433 100644 --- a/tests/baselines/reference/tupleLengthCheck.errors.txt +++ b/tests/baselines/reference/tupleLengthCheck.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/types/tuple/tupleLengthCheck.ts(5,14): error TS2339: Property '2' does not exist on type '[number, string]'. -tests/cases/conformance/types/tuple/tupleLengthCheck.ts(6,14): error TS2339: Property '1000' does not exist on type '[number, string]'. +tests/cases/conformance/types/tuple/tupleLengthCheck.ts(5,14): error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. +tests/cases/conformance/types/tuple/tupleLengthCheck.ts(6,14): error TS2493: Tuple type '[number, string]' of length '2' has no element at index '1000'. ==== tests/cases/conformance/types/tuple/tupleLengthCheck.ts (2 errors) ==== @@ -9,10 +9,10 @@ tests/cases/conformance/types/tuple/tupleLengthCheck.ts(6,14): error TS2339: Pro const a1 = a[1] const a2 = a[2] ~ -!!! error TS2339: Property '2' does not exist on type '[number, string]'. +!!! error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. const a3 = a[1000] ~~~~ -!!! error TS2339: Property '1000' does not exist on type '[number, string]'. +!!! error TS2493: Tuple type '[number, string]' of length '2' has no element at index '1000'. const a4 = rest[1] const a5 = rest[2] diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index 3776a92d6a131..1cf2f113d1470 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/tupleTypes.ts(11,12): error TS2339: Property '2' does not exist on type '[number, string]'. +tests/cases/compiler/tupleTypes.ts(11,12): error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. tests/cases/compiler/tupleTypes.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type 'undefined', but here has type 'string | number'. tests/cases/compiler/tupleTypes.ts(14,1): error TS2739: Type '[]' is missing the following properties from type '[number, string]': 0, 1 tests/cases/compiler/tupleTypes.ts(15,1): error TS2741: Property '1' is missing in type '[number]' but required in type '[number, string]'. @@ -7,7 +7,7 @@ tests/cases/compiler/tupleTypes.ts(17,15): error TS2322: Type 'number' is not as tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, number]' is not assignable to type '[number, string]'. Types of property 'length' are incompatible. Type '3' is not assignable to type '2'. -tests/cases/compiler/tupleTypes.ts(35,14): error TS2339: Property '2' does not exist on type '[number, string]'. +tests/cases/compiler/tupleTypes.ts(35,14): error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. tests/cases/compiler/tupleTypes.ts(36,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'tt2' must be of type 'undefined', but here has type 'string | number'. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type '[]' is not assignable to type '[number, string]'. tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. @@ -35,7 +35,7 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n var t1: string; var t2 = t[2]; // number|string ~ -!!! error TS2339: Property '2' does not exist on type '[number, string]'. +!!! error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. var t2: number|string; ~~ !!! error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type 'undefined', but here has type 'string | number'. @@ -75,7 +75,7 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n var tt1: string; var tt2 = tt[2]; ~ -!!! error TS2339: Property '2' does not exist on type '[number, string]'. +!!! error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. var tt2: number | string; ~~~ !!! error TS2403: Subsequent variable declarations must have the same type. Variable 'tt2' must be of type 'undefined', but here has type 'string | number'. diff --git a/tests/baselines/reference/unionsOfTupleTypes1.errors.txt b/tests/baselines/reference/unionsOfTupleTypes1.errors.txt index d9cad5f1b11c9..da997e988eef5 100644 --- a/tests/baselines/reference/unionsOfTupleTypes1.errors.txt +++ b/tests/baselines/reference/unionsOfTupleTypes1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(8,15): error TS2339: Property '2' does not exist on type '[string, number]'. +tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(8,15): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(13,15): error TS2339: Property '2' does not exist on type 'T2'. -tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(27,20): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. -tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(28,20): error TS2460: Type 'T2' has no property '2'. -tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(31,16): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. -tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(32,16): error TS2460: Type 'T2' has no property '2'. -tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(37,18): error TS2339: Property '2' does not exist on type '[string, number]'. +tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(27,20): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. +tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(28,20): error TS2339: Property '2' does not exist on type 'T2'. +tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(31,16): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. +tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(32,16): error TS2339: Property '2' does not exist on type 'T2'. +tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(37,18): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(41,18): error TS2339: Property '2' does not exist on type 'T2'. @@ -18,7 +18,7 @@ tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(41,18): error TS2339: type T11 = T1[1]; // number type T12 = T1[2]; // undefined ~ -!!! error TS2339: Property '2' does not exist on type '[string, number]'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. type T1N = T1[number]; // string | number type T20 = T2[0]; // string | boolean @@ -41,25 +41,25 @@ tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(41,18): error TS2339: function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) { let [d10, d11, d12] = t1; // string, number ~~~ -!!! error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. let [d20, d21, d22] = t2; // string | boolean, number | undefined ~~~ -!!! error TS2460: Type 'T2' has no property '2'. +!!! error TS2339: Property '2' does not exist on type 'T2'. let [d30, d31, d32] = t3; // string, number, number let [d40, d41, d42] = t4; // string | boolean, number | undefined, number | undefined [d10, d11, d12] = t1; ~~~ -!!! error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. [d20, d21, d22] = t2; ~~~ -!!! error TS2460: Type 'T2' has no property '2'. +!!! error TS2339: Property '2' does not exist on type 'T2'. [d30, d31, d32] = t3; [d40, d41, d42] = t4; let t10 = t1[0]; // string let t11 = t1[1]; // number let t12 = t1[2]; // undefined ~ -!!! error TS2339: Property '2' does not exist on type '[string, number]'. +!!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. let t1x = t1[x]; // string | number let t20 = t2[0]; // string | boolean let t21 = t2[1]; // number | undefined diff --git a/tests/baselines/reference/unionsOfTupleTypes1.types b/tests/baselines/reference/unionsOfTupleTypes1.types index e44114f5a6a05..e0867cd104568 100644 --- a/tests/baselines/reference/unionsOfTupleTypes1.types +++ b/tests/baselines/reference/unionsOfTupleTypes1.types @@ -70,13 +70,13 @@ function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) { let [d10, d11, d12] = t1; // string, number >d10 : string >d11 : number ->d12 : any +>d12 : undefined >t1 : [string, number] let [d20, d21, d22] = t2; // string | boolean, number | undefined >d20 : string | boolean >d21 : number | undefined ->d22 : any +>d22 : undefined >t2 : T2 let [d30, d31, d32] = t3; // string, number, number @@ -93,18 +93,18 @@ function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) { [d10, d11, d12] = t1; >[d10, d11, d12] = t1 : [string, number] ->[d10, d11, d12] : [string, number, any] +>[d10, d11, d12] : [string, number, undefined] >d10 : string >d11 : number ->d12 : any +>d12 : undefined >t1 : [string, number] [d20, d21, d22] = t2; >[d20, d21, d22] = t2 : T2 ->[d20, d21, d22] : [string | boolean, number | undefined, any] +>[d20, d21, d22] : [string | boolean, number | undefined, undefined] >d20 : string | boolean >d21 : number | undefined ->d22 : any +>d22 : undefined >t2 : T2 [d30, d31, d32] = t3; diff --git a/tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts b/tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts new file mode 100644 index 0000000000000..033f2bdb75e84 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts @@ -0,0 +1,36 @@ +// @strict: true + +function f1(obj: { a?: string }) { + if (obj.a) { + obj = {}; + let a1 = obj["a"]; // string | undefined + let a2 = obj.a; // string | undefined + } +} + +function f2(obj: [number, string] | null[]) { + let a0 = obj[0]; // number | null + let a1 = obj[1]; // string | null + let [b0, b1] = obj; + ([a0, a1] = obj); + if (obj[0] && obj[1]) { + let c0 = obj[0]; // number + let c1 = obj[1]; // string + let [d0, d1] = obj; + ([c0, c1] = obj); + } +} + +function f3(obj: { a?: number, b?: string }) { + if (obj.a && obj.b) { + let { a, b } = obj; // number, string + ({ a, b } = obj); + } +} + +function f4() { + let x: boolean; + ({ x } = 0); // Error + ({ ["x"]: x } = 0); // Error + ({ ["x" + ""]: x } = 0); // Errpr +}