mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-11 20:37:46 -05:00
Only infer readonly tuples for const type parameters when constraints permit (#55229)
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
This commit is contained in:
@@ -23674,6 +23674,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
|
||||
}
|
||||
|
||||
function isMutableArrayLikeType(type: Type): boolean {
|
||||
// A type is mutable-array-like if it is a reference to the global Array type, or if it is not the
|
||||
// any, undefined or null type and if it is assignable to Array<any>
|
||||
return isMutableArrayOrTuple(type) || !(type.flags & (TypeFlags.Any | TypeFlags.Nullable)) && isTypeAssignableTo(type, anyArrayType);
|
||||
}
|
||||
|
||||
function getSingleBaseForNonAugmentingSubtype(type: Type) {
|
||||
if (!(getObjectFlags(type) & ObjectFlags.Reference) || !(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface)) {
|
||||
return undefined;
|
||||
@@ -24338,7 +24344,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
|
||||
}
|
||||
if (targetRestType) {
|
||||
callback(getRestTypeAtPosition(source, paramCount), targetRestType);
|
||||
callback(getRestTypeAtPosition(source, paramCount, /*readonly*/ isConstTypeVariable(targetRestType) && !someType(targetRestType, isMutableArrayLikeType)), targetRestType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30541,7 +30547,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return createTupleType(elementTypes, elementFlags);
|
||||
}
|
||||
if (forceTuple || inConstContext || inTupleContext) {
|
||||
return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext));
|
||||
return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext && !(contextualType && someType(contextualType, isMutableArrayLikeType))));
|
||||
}
|
||||
return createArrayLiteralType(createArrayType(
|
||||
elementTypes.length ?
|
||||
@@ -33139,7 +33145,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
names.push((arg as SyntheticExpression).tupleNameSource!);
|
||||
}
|
||||
}
|
||||
return createTupleType(types, flags, inConstContext, length(names) === length(types) ? names : undefined);
|
||||
return createTupleType(types, flags, inConstContext && !someType(restType, isMutableArrayLikeType), length(names) === length(types) ? names : undefined);
|
||||
}
|
||||
|
||||
function checkTypeArguments(signature: Signature, typeArgumentNodes: readonly TypeNode[], reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | undefined {
|
||||
@@ -35455,7 +35461,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getRestTypeAtPosition(source: Signature, pos: number): Type {
|
||||
function getRestTypeAtPosition(source: Signature, pos: number, readonly?: boolean): Type {
|
||||
const parameterCount = getParameterCount(source);
|
||||
const minArgumentCount = getMinArgumentCount(source);
|
||||
const restType = getEffectiveRestType(source);
|
||||
@@ -35479,7 +35485,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
names.push(name);
|
||||
}
|
||||
}
|
||||
return createTupleType(types, flags, /*readonly*/ false, length(names) === length(types) ? names : undefined);
|
||||
return createTupleType(types, flags, readonly, length(names) === length(types) ? names : undefined);
|
||||
}
|
||||
|
||||
// Return the number of parameters in a signature. The rest parameter, if present, counts as one
|
||||
|
||||
Reference in New Issue
Block a user