Skip to content

Commit

Permalink
More comprehensive check for mutability
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed Aug 3, 2023
1 parent f6833cd commit 52fe112
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23265,6 +23265,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 array-like if it is a reference to the global Array or global ReadonlyArray type,
// or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
return isMutableArrayOrTuple(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyArrayType);
}

function getSingleBaseForNonAugmentingSubtype(type: Type) {
if (!(getObjectFlags(type) & ObjectFlags.Reference) || !(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface)) {
return undefined;
Expand Down Expand Up @@ -23925,7 +23931,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
}
if (targetRestType) {
callback(getRestTypeAtPosition(source, paramCount, /*readonly*/ isConstTypeVariable(targetRestType) && !isMutableArrayOrTuple(getBaseConstraintOrType(targetRestType))), targetRestType);
callback(getRestTypeAtPosition(source, paramCount, /*readonly*/ isConstTypeVariable(targetRestType) && !isMutableArrayLikeType(targetRestType)), targetRestType);
}
}

Expand Down Expand Up @@ -30045,7 +30051,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return createTupleType(elementTypes, elementFlags);
}
if (forceTuple || inConstContext || inTupleContext) {
return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext && !(contextualType && isMutableArrayOrTuple(contextualType))));
return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext && !(contextualType && isMutableArrayLikeType(contextualType))));
}
return createArrayLiteralType(createArrayType(elementTypes.length ?
getUnionType(sameMap(elementTypes, (t, i) => elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessTypeOrUndefined(t, numberType) || anyType : t), UnionReduction.Subtype) :
Expand Down Expand Up @@ -32623,7 +32629,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
names.push((arg as SyntheticExpression).tupleNameSource!);
}
}
return createTupleType(types, flags, inConstContext && !isMutableArrayOrTuple(getBaseConstraintOrType(restType)), length(names) === length(types) ? names : undefined);
return createTupleType(types, flags, inConstContext && !isMutableArrayLikeType(restType), length(names) === length(types) ? names : undefined);
}

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

0 comments on commit 52fe112

Please sign in to comment.