-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Closed
Labels
enhancement: new plugin ruleNew rule request for eslint-pluginNew rule request for eslint-pluginpackage: eslint-pluginIssues related to @typescript-eslint/eslint-pluginIssues related to @typescript-eslint/eslint-plugintriageWaiting for team members to take a lookWaiting for team members to take a look
Description
Before You File a Proposal Please Confirm You Have Done The Following...
- I have searched for related issues and found none that match my proposal.
- I have searched the current rule list and found no rules that match my proposal.
- I have read the FAQ and my problem is not listed.
My proposal is suitable for this project
- My proposal specifically checks TypeScript syntax, or it proposes a check that requires type information to be accurate.
- My proposal is not a "formatting rule"; meaning it does not just enforce how code is formatted (whitespace, brace placement, etc).
- I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).
Description
TypeScript silently allows an expression of type Readonly<T> to be passed as an argument of type T. This results in a loss of the readonly type information in the scope of the called function and potential unintended mutation.
Fail Cases
// Declaring a variable Readonly should guard against future modification, even at a lower scope
const dangerous: Readonly<number[]> = getDangerousToModify();
// Fails since pushOne() requires a mutable argument
pushOne(dangerous);
function pushOne(a: number[]): void { a.push(1); };Pass Cases
// Making a copy results in a mutable array, so the rule accepts this
const dangerousCopy = [...dangerous];
pushOne(dangerousCopy);
// If mutation is really intended, type assertion will also be accepted
pushOne(dangerous as number[]);Additional Info
In combination with explicit this parameters, this also enables methods to declare they are guaranteed not to modify the object:
class Vec3 {
constructor(public x: number, public y: number, public z: number) {}
norm(this: Readonly<this>): number {
return Math.hypot(this.x, this.y, this.z);
}
}Metadata
Metadata
Assignees
Labels
enhancement: new plugin ruleNew rule request for eslint-pluginNew rule request for eslint-pluginpackage: eslint-pluginIssues related to @typescript-eslint/eslint-pluginIssues related to @typescript-eslint/eslint-plugintriageWaiting for team members to take a lookWaiting for team members to take a look