mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-18 07:29:16 -05:00
Assignment rest element pretends to get the contextual element type
This commit is contained in:
@@ -6011,14 +6011,38 @@ module ts {
|
||||
}
|
||||
let hasSpreadElement = false;
|
||||
let elementTypes: Type[] = [];
|
||||
let inDestructuringPattern = isAssignmentTarget(node);
|
||||
for (let e of elements) {
|
||||
let type = checkExpression(e, contextualMapper);
|
||||
elementTypes.push(type);
|
||||
if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElementExpression) {
|
||||
// Given the following situation:
|
||||
// var c: {};
|
||||
// [...c] = ["", 0];
|
||||
//
|
||||
// c is represented in the tree as a spread element in an array literal.
|
||||
// But c really functions as a rest element, and its purpose is to provide
|
||||
// a contextual type for the right hand side of the assignment. Therefore,
|
||||
// instead of calling checkExpression on "...c", which will give an error
|
||||
// if c is not iterable/array-like, we need to act as if we are trying to
|
||||
// get the contextual element type from it. So we do something similar to
|
||||
// getContextualTypeForElementExpression, which will crucially not error
|
||||
// if there is no index type / iterated type.
|
||||
let restArrayType = checkExpression((<SpreadElementExpression>e).expression, contextualMapper);
|
||||
let restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
|
||||
(languageVersion >= ScriptTarget.ES6 ? checkIteratedType(restArrayType, /*expressionForError*/ undefined) : undefined);
|
||||
|
||||
if (restElementType) {
|
||||
elementTypes.push(restElementType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let type = checkExpression(e, contextualMapper);
|
||||
elementTypes.push(type);
|
||||
}
|
||||
hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElementExpression;
|
||||
}
|
||||
if (!hasSpreadElement) {
|
||||
let contextualType = getContextualType(node);
|
||||
if (contextualType && contextualTypeIsTupleLikeType(contextualType) || isAssignmentTarget(node)) {
|
||||
if (contextualType && contextualTypeIsTupleLikeType(contextualType) || inDestructuringPattern) {
|
||||
return createTupleType(elementTypes);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user