Fixed an issue with not being able to use mapped type over union constraint as rest param (#49947)

This commit is contained in:
Mateusz Burzyński
2023-03-20 19:14:25 +01:00
committed by GitHub
parent 27aca613ff
commit 1ed06e6b05
11 changed files with 429 additions and 3 deletions

View File

@@ -13861,7 +13861,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const typeVariable = getHomomorphicTypeVariable(type);
if (typeVariable && !type.declaration.nameType) {
const constraint = getConstraintOfTypeParameter(typeVariable);
if (constraint && isArrayType(constraint)) {
if (constraint && everyType(constraint, isArrayOrTupleType)) {
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
}
}
@@ -21686,7 +21686,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return varianceResult;
}
}
else if (isReadonlyArrayType(target) ? isArrayOrTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
else if (isReadonlyArrayType(target) ? everyType(source, isArrayOrTupleType) : isArrayType(target) && everyType(source, t => isTupleType(t) && !t.target.readonly)) {
if (relation !== identityRelation) {
return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, RecursionFlags.Both, reportErrors);
}
@@ -29258,7 +29258,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
getContextualType(node, contextFlags);
const instantiatedType = instantiateContextualType(contextualType, node, contextFlags);
if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && instantiatedType.flags & TypeFlags.TypeVariable)) {
const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true);
const apparentType = mapType(
instantiatedType,
// When obtaining apparent type of *contextual* type we don't want to get apparent type of mapped types.
// That would evaluate mapped types with array or tuple type constraints too eagerly
// and thus it would prevent `getTypeOfPropertyOfContextualType` from obtaining per-position contextual type for elements of array literal expressions.
// Apparent type of other mapped types is already the mapped type itself so we can just avoid calling `getApparentType` here for all mapped types.
t => getObjectFlags(t) & ObjectFlags.Mapped ? t : getApparentType(t),
/*noReductions*/ true
);
return apparentType.flags & TypeFlags.Union && isObjectLiteralExpression(node) ? discriminateContextualTypeByObjectMembers(node, apparentType as UnionType) :
apparentType.flags & TypeFlags.Union && isJsxAttributes(node) ? discriminateContextualTypeByJSXAttributes(node, apparentType as UnionType) :
apparentType;