mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-10 15:25:54 -06:00
Evolving array element ignores contextual type
Control flow analysis can easily hit circularities or exponential behaviour when requesting the contextual type of an expression. When adding an element type to an evolving array type, there is no point in checking the contextual type of the new element type because it is unknown -- it is exactly the type of the evolving array, which is in the middle of being found. Fixes #14628 This is code of the form: ```ts let x = [] x[0] = { contextual: 'no' } x[1] = { contextual: 'should not check' } x[2] = { contextual: 'contextual type' } // : // : ```
This commit is contained in:
parent
3029b8fe38
commit
5c2091ad33
@ -10893,7 +10893,7 @@ namespace ts {
|
||||
// we defer subtype reduction until the evolving array type is finalized into a manifest
|
||||
// array type.
|
||||
function addEvolvingArrayElementType(evolvingArrayType: EvolvingArrayType, node: Expression): EvolvingArrayType {
|
||||
const elementType = getBaseTypeOfLiteralType(getTypeOfExpression(node));
|
||||
const elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node));
|
||||
return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
|
||||
}
|
||||
|
||||
@ -17064,10 +17064,12 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
// Returns the type of an expression. Unlike checkExpression, this function is simply concerned
|
||||
// with computing the type and may not fully check all contained sub-expressions for errors.
|
||||
// A cache argument of true indicates that if the function performs a full type check, it is ok
|
||||
// to cache the result.
|
||||
/**
|
||||
* Returns the type of an expression. Unlike checkExpression, this function is simply concerned
|
||||
* with computing the type and may not fully check all contained sub-expressions for errors.
|
||||
* A cache argument of true indicates that if the function performs a full type check, it is ok
|
||||
* to cache the result.
|
||||
*/
|
||||
function getTypeOfExpression(node: Expression, cache?: boolean) {
|
||||
// Optimize for the common case of a call to a function with a single non-generic call
|
||||
// signature where we can just fetch the return type without checking the arguments.
|
||||
@ -17084,6 +17086,21 @@ namespace ts {
|
||||
return cache ? checkExpressionCached(node) : checkExpression(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of an expression. Unlike checkExpression, this function is simply concerned
|
||||
* with computing the type and may not fully check all contained sub-expressions for errors.
|
||||
* It is intended for uses where you know there is no contextual type,
|
||||
* and requesting the contextual type might cause a circularity or other bad behaviour.
|
||||
* It sets the contextual type of the node to any before calling getTypeOfExpression.
|
||||
*/
|
||||
function getContextFreeTypeOfExpression(node: Expression) {
|
||||
const saveContextualType = node.contextualType;
|
||||
node.contextualType = anyType;
|
||||
const type = getTypeOfExpression(node);
|
||||
node.contextualType = saveContextualType;
|
||||
return type;
|
||||
}
|
||||
|
||||
// Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When
|
||||
// contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the
|
||||
// expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user