Skip to content

Commit

Permalink
Fix microsoft#55632 (taking care of elements / tuples length)
Browse files Browse the repository at this point in the history
  • Loading branch information
fwolff committed Oct 30, 2024
1 parent 762fd14 commit a6c7faa
Showing 1 changed file with 30 additions and 13 deletions.
43 changes: 30 additions & 13 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31877,19 +31877,36 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function discriminateContextualTypeByArrayElements(node: ArrayLiteralExpression, contextualType: UnionType) {
const key = `D${getNodeId(node)},${getTypeId(contextualType)}`;
return getCachedType(key) ?? setCachedType(
key,
discriminateTypeByDiscriminableItems(
contextualType,
node.elements.map((element, index) => {
const name = ("" + index) as __String
return isPossiblyDiscriminantValue(element) && isDiscriminantProperty(contextualType, name) ?
[() => getContextFreeTypeOfExpression(element), name] as const :
undefined
}).filter(e => !!e),
isTypeAssignableTo,
),
);
const cached = getCachedType(key);
if (cached) return cached;

if (!contextualType.types.every(type => getObjectFlags(getTargetType(type)) & ObjectFlags.Tuple))
return setCachedType(key, contextualType)

const elementsLength = node.elements.length;
const filteredTupleTypesByLength = filter(contextualType.types, type => {
const tupleType = ((type as TypeReference).target as TupleType);
return (
elementsLength >= tupleType.minLength &&
((tupleType.combinedFlags & ElementFlags.Variable) !== 0 || elementsLength <= tupleType.fixedLength)
)
})
if (filteredTupleTypesByLength !== contextualType.types) {
if (filteredTupleTypesByLength.length < 2)
return setCachedType(key, filteredTupleTypesByLength.length ? filteredTupleTypesByLength[0] : contextualType);
contextualType = getUnionType(filteredTupleTypesByLength, UnionReduction.None) as UnionType;
}

return setCachedType(key, discriminateTypeByDiscriminableItems(
contextualType,
node.elements.map((element, index) => {
const name = ("" + index) as __String
return isPossiblyDiscriminantValue(element) && isDiscriminantProperty(contextualType, name) ?
[() => getContextFreeTypeOfExpression(element), name] as const :
undefined
}).filter(discriminator => !!discriminator),
isTypeAssignableTo,
));
}

// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
Expand Down

0 comments on commit a6c7faa

Please sign in to comment.