Skip to content

Commit 52fe112

Browse files
committed
More comprehensive check for mutability
1 parent f6833cd commit 52fe112

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23265,6 +23265,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2326523265
return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
2326623266
}
2326723267

23268+
function isMutableArrayLikeType(type: Type): boolean {
23269+
// A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
23270+
// or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
23271+
return isMutableArrayOrTuple(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyArrayType);
23272+
}
23273+
2326823274
function getSingleBaseForNonAugmentingSubtype(type: Type) {
2326923275
if (!(getObjectFlags(type) & ObjectFlags.Reference) || !(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface)) {
2327023276
return undefined;
@@ -23925,7 +23931,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2392523931
callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
2392623932
}
2392723933
if (targetRestType) {
23928-
callback(getRestTypeAtPosition(source, paramCount, /*readonly*/ isConstTypeVariable(targetRestType) && !isMutableArrayOrTuple(getBaseConstraintOrType(targetRestType))), targetRestType);
23934+
callback(getRestTypeAtPosition(source, paramCount, /*readonly*/ isConstTypeVariable(targetRestType) && !isMutableArrayLikeType(targetRestType)), targetRestType);
2392923935
}
2393023936
}
2393123937

@@ -30045,7 +30051,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3004530051
return createTupleType(elementTypes, elementFlags);
3004630052
}
3004730053
if (forceTuple || inConstContext || inTupleContext) {
30048-
return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext && !(contextualType && isMutableArrayOrTuple(contextualType))));
30054+
return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext && !(contextualType && isMutableArrayLikeType(contextualType))));
3004930055
}
3005030056
return createArrayLiteralType(createArrayType(elementTypes.length ?
3005130057
getUnionType(sameMap(elementTypes, (t, i) => elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessTypeOrUndefined(t, numberType) || anyType : t), UnionReduction.Subtype) :
@@ -32623,7 +32629,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3262332629
names.push((arg as SyntheticExpression).tupleNameSource!);
3262432630
}
3262532631
}
32626-
return createTupleType(types, flags, inConstContext && !isMutableArrayOrTuple(getBaseConstraintOrType(restType)), length(names) === length(types) ? names : undefined);
32632+
return createTupleType(types, flags, inConstContext && !isMutableArrayLikeType(restType), length(names) === length(types) ? names : undefined);
3262732633
}
3262832634

3262932635
function checkTypeArguments(signature: Signature, typeArgumentNodes: readonly TypeNode[], reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | undefined {

0 commit comments

Comments
 (0)