mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #29053 from Microsoft/fixDestructuringControlFlow
Fix destructuring control flow analysis
This commit is contained in:
+170
-187
@@ -4783,6 +4783,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 = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression, node.pos, node.end);
|
||||
result.parent = node;
|
||||
result.expression = <LeftHandSideExpression>parentAccess;
|
||||
const literal = <StringLiteral>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(<BindingElement | PropertyAssignment>ancestor);
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return getSyntheticElementAccess(<Expression>node.parent);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return (<VariableDeclaration>ancestor).initializer;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return (<BinaryExpression>ancestor).right;
|
||||
}
|
||||
}
|
||||
|
||||
function getDestructuringPropertyName(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression) {
|
||||
const parent = node.parent;
|
||||
if (node.kind === SyntaxKind.BindingElement && parent.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
return getLiteralPropertyNameText((<BindingElement>node).propertyName || <Identifier>(<BindingElement>node).name);
|
||||
}
|
||||
if (node.kind === SyntaxKind.PropertyAssignment || node.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
return getLiteralPropertyNameText((<PropertyAssignment | ShorthandPropertyAssignment>node).name);
|
||||
}
|
||||
return "" + (<NodeArray<Node>>(<BindingPattern | ArrayLiteralExpression>parent).elements).indexOf(node);
|
||||
}
|
||||
|
||||
function getLiteralPropertyNameText(name: PropertyName) {
|
||||
const type = getLiteralTypeFromPropertyName(name);
|
||||
return type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral) ? "" + (<LiteralType>type).value : undefined;
|
||||
}
|
||||
|
||||
/** Return the inferred type for a binding element */
|
||||
function getTypeForBindingElement(declaration: BindingElement): Type | undefined {
|
||||
const pattern = declaration.parent;
|
||||
@@ -4823,9 +4886,9 @@ namespace ts {
|
||||
else {
|
||||
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
|
||||
const name = declaration.propertyName || <Identifier>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 {
|
||||
@@ -4842,21 +4905,13 @@ namespace ts {
|
||||
mapType(parentType, t => sliceTupleType(<TupleTypeReference>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(<TypeReference>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
|
||||
@@ -9538,16 +9593,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((<PropertyAccessExpression>accessExpression.argumentExpression).name))
|
||||
: accessNode && isPropertyName(accessNode)
|
||||
const propName = isTypeUsableAsLateBoundName(indexType) ?
|
||||
getLateBoundNameFromType(indexType) :
|
||||
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
|
||||
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>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) {
|
||||
@@ -9569,7 +9624,13 @@ namespace ts {
|
||||
if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) {
|
||||
if (accessNode && everyType(objectType, t => !(<TupleTypeReference>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(<TupleTypeReference>t) || undefinedType);
|
||||
}
|
||||
@@ -9641,7 +9702,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
|
||||
@@ -9710,7 +9771,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;
|
||||
}
|
||||
@@ -14587,49 +14648,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(<Identifier>node);
|
||||
return symbol !== unknownSymbol ? (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
|
||||
}
|
||||
if (node.kind === SyntaxKind.ThisKeyword) {
|
||||
return "0";
|
||||
}
|
||||
if (node.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const key = getFlowCacheKey((<PropertyAccessExpression>node).expression);
|
||||
return key && key + "." + idText((<PropertyAccessExpression>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(<Identifier>node);
|
||||
return symbol !== unknownSymbol ? (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return "0";
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
const propName = getAccessedPropertyName(<AccessExpression>node);
|
||||
if (propName !== undefined) {
|
||||
const key = getFlowCacheKey((<AccessExpression>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:
|
||||
@@ -14642,49 +14677,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 && (<PropertyAccessExpression>target).name.escapedText === getBindingElementNameText(<BindingElement>source)) {
|
||||
const ancestor = source.parent.parent;
|
||||
if (ancestor.kind === SyntaxKind.BindingElement) {
|
||||
return isMatchingReference(ancestor, (<PropertyAccessExpression>target).expression);
|
||||
}
|
||||
if (ancestor.kind === SyntaxKind.VariableDeclaration) {
|
||||
const initializer = (<VariableDeclaration>ancestor).initializer;
|
||||
return !!initializer && isMatchingReference(initializer, (<PropertyAccessExpression>target).expression);
|
||||
}
|
||||
}
|
||||
return isAccessExpression(target) &&
|
||||
getAccessedPropertyName(<AccessExpression>source) === getAccessedPropertyName(target) &&
|
||||
isMatchingReference((<AccessExpression>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 (<PropertyAccessExpression>source).expression;
|
||||
}
|
||||
if (source.kind === SyntaxKind.BindingElement) {
|
||||
const ancestor = source.parent.parent;
|
||||
return ancestor.kind === SyntaxKind.VariableDeclaration ? (<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
|
||||
@@ -14692,18 +14705,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, (<PropertyAccessExpression>target).expression) &&
|
||||
isDiscriminantProperty(getDeclaredTypeOfReference((<PropertyAccessExpression>target).expression), (<PropertyAccessExpression>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(<Identifier>expr));
|
||||
}
|
||||
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const type = getDeclaredTypeOfReference((<PropertyAccessExpression>expr).expression);
|
||||
return type && getTypeOfPropertyOfType(type, (<PropertyAccessExpression>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;
|
||||
}
|
||||
@@ -15529,7 +15547,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)) {
|
||||
@@ -15649,21 +15667,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);
|
||||
@@ -15676,7 +15692,7 @@ namespace ts {
|
||||
return getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy);
|
||||
}
|
||||
if (isMatchingReferenceDiscriminant(expr, declaredType)) {
|
||||
return narrowTypeByDiscriminant(type, <PropertyAccessExpression | ElementAccessExpression>expr, t => getTypeWithFacts(t, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy));
|
||||
return narrowTypeByDiscriminant(type, <AccessExpression>expr, t => getTypeWithFacts(t, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy));
|
||||
}
|
||||
if (containsMatchingReferenceDiscriminant(reference, expr)) {
|
||||
return declaredType;
|
||||
@@ -15727,10 +15743,10 @@ namespace ts {
|
||||
return narrowTypeByEquality(type, operator, left, assumeTrue);
|
||||
}
|
||||
if (isMatchingReferenceDiscriminant(left, declaredType)) {
|
||||
return narrowTypeByDiscriminant(type, <PropertyAccessExpression | ElementAccessExpression>left, t => narrowTypeByEquality(t, operator, right, assumeTrue));
|
||||
return narrowTypeByDiscriminant(type, <AccessExpression>left, t => narrowTypeByEquality(t, operator, right, assumeTrue));
|
||||
}
|
||||
if (isMatchingReferenceDiscriminant(right, declaredType)) {
|
||||
return narrowTypeByDiscriminant(type, <PropertyAccessExpression | ElementAccessExpression>right, t => narrowTypeByEquality(t, operator, left, assumeTrue));
|
||||
return narrowTypeByDiscriminant(type, <AccessExpression>right, t => narrowTypeByEquality(t, operator, left, assumeTrue));
|
||||
}
|
||||
if (containsMatchingReferenceDiscriminant(reference, left) || containsMatchingReferenceDiscriminant(reference, right)) {
|
||||
return declaredType;
|
||||
@@ -16035,9 +16051,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);
|
||||
}
|
||||
@@ -16980,7 +16995,7 @@ namespace ts {
|
||||
if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
const target = (<BinaryExpression>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);
|
||||
@@ -19736,7 +19751,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21768,7 +21783,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)) {
|
||||
@@ -21786,7 +21801,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) {
|
||||
@@ -22035,21 +22050,18 @@ namespace ts {
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: NodeArray<ObjectLiteralElementLike>, 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) {
|
||||
@@ -22070,31 +22082,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).
|
||||
@@ -22111,39 +22103,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(<TypeReference>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 = (<SpreadElement>element).expression;
|
||||
if (restExpression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>restExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
error((<BinaryExpression>restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
}
|
||||
else {
|
||||
const restExpression = (<SpreadElement>element).expression;
|
||||
if (restExpression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>restExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
error((<BinaryExpression>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(<TupleTypeReference>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(<TupleTypeReference>t, elementIndex)) :
|
||||
createArrayType(elementType);
|
||||
return checkDestructuringAssignment(restExpression, type, checkMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26982,7 +26965,7 @@ namespace ts {
|
||||
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
const ex = <PropertyAccessExpression | ElementAccessExpression>expr;
|
||||
const ex = <AccessExpression>expr;
|
||||
if (isConstantMemberAccess(ex)) {
|
||||
const type = getTypeOfExpression(ex.expression);
|
||||
if (type.symbol && type.symbol.flags & SymbolFlags.Enum) {
|
||||
@@ -28956,7 +28939,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:
|
||||
@@ -28966,7 +28949,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);
|
||||
}
|
||||
|
||||
@@ -1644,14 +1644,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
|
||||
@@ -1768,7 +1760,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
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<string|number> {
|
||||
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]'.
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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]'.
|
||||
!!! error TS2493: Tuple type '[E1, E2, number]' of length '3' has no element at index '3'.
|
||||
@@ -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'.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 '{}'.
|
||||
|
||||
|
||||
@@ -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 '{}'.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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'.
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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'.
|
||||
});
|
||||
@@ -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'.
|
||||
}
|
||||
}
|
||||
@@ -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 '[]'.
|
||||
!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'.
|
||||
@@ -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 '[]'.
|
||||
!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'.
|
||||
@@ -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"];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
>"" : ""
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
!!! error TS2339: Property 'b' does not exist on type '(string | number)[]'.
|
||||
@@ -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.
|
||||
!!! error TS2339: Property 'b' does not exist on type '[string, number]'.
|
||||
@@ -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 '{}'.
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+4
-4
@@ -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 '{}'.
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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'.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user