Never mutate caller inputs
Rule
Exported functions never modify their arguments. Type array and object parameters as readonly. To sort, filter or update, copy first and return the new value. Methods that change an object’s own state are allowed only when the type is documented as mutable.
Do
export interface Scored {
readonly id: string;
readonly score: number;
}
export function rank(results: readonly Scored[]): Scored[] {
return [...results].sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
}Don’t
export interface Scored {
id: string;
score: number;
}
export function rank(results: Scored[]): Scored[] {
// Reorders the caller's array in place.
return results.sort((a, b) => b.score - a.score);
}Rationale
A caller that passes its own data cannot predict an in-place change, and the resulting bugs show up far from the call. readonly parameter types turn most mutations into compile errors. Source: the immutable-API requirement in Package Conventions.