Skip to content

Commit a49b860

Browse files
authored
feat(eslint-plugin): add rule no-unsafe-assignment (typescript-eslint#1694)
1 parent 829a2f7 commit a49b860

File tree

9 files changed

+802
-14
lines changed

9 files changed

+802
-14
lines changed

packages/eslint-plugin/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int
134134
| [`@typescript-eslint/no-unnecessary-qualifier`](./docs/rules/no-unnecessary-qualifier.md) | Warns when a namespace qualifier is unnecessary | | :wrench: | :thought_balloon: |
135135
| [`@typescript-eslint/no-unnecessary-type-arguments`](./docs/rules/no-unnecessary-type-arguments.md) | Enforces that type arguments will not be used if not required | | :wrench: | :thought_balloon: |
136136
| [`@typescript-eslint/no-unnecessary-type-assertion`](./docs/rules/no-unnecessary-type-assertion.md) | Warns if a type assertion does not change the type of an expression | :heavy_check_mark: | :wrench: | :thought_balloon: |
137+
| [`@typescript-eslint/no-unsafe-assignment`](./docs/rules/no-unsafe-assignment.md) | Disallows assigning any to variables and properties | | | :thought_balloon: |
137138
| [`@typescript-eslint/no-unsafe-call`](./docs/rules/no-unsafe-call.md) | Disallows calling an any type value | | | :thought_balloon: |
138139
| [`@typescript-eslint/no-unsafe-member-access`](./docs/rules/no-unsafe-member-access.md) | Disallows member access on any typed variables | | | :thought_balloon: |
139140
| [`@typescript-eslint/no-unsafe-return`](./docs/rules/no-unsafe-return.md) | Disallows returning any from a function | | | :thought_balloon: |
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Disallows assigning any to variables and properties (`no-unsafe-assignment`)
2+
3+
Despite your best intentions, the `any` type can sometimes leak into your codebase.
4+
Assigning an `any` typed value to a variable can be hard to pick up on, particularly if it leaks in from an external library. Operations on the variable will not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase.
5+
6+
## Rule Details
7+
8+
This rule disallows the assigning `any` to a variable, and assigning `any[]` to an array destructuring.
9+
This rule also compares the assigned type to the variable's declared/inferred return type to ensure you don't return an unsafe `any` in a generic position to a receiver that's expecting a specific type. For example, it will error if you return `Set<any>` from a function declared as returning `Set<string>`.
10+
11+
Examples of **incorrect** code for this rule:
12+
13+
```ts
14+
const x = 1 as any,
15+
y = 1 as any;
16+
const [x] = 1 as any;
17+
const [x] = [] as any[];
18+
const [x] = [1 as any];
19+
[x] = [1] as [any];
20+
21+
function foo(a = 1 as any) {}
22+
class Foo {
23+
constructor(private a = 1 as any) {}
24+
}
25+
class Foo {
26+
private a = 1 as any;
27+
}
28+
29+
// generic position examples
30+
const x: Set<string> = new Set<any>();
31+
const x: Map<string, string> = new Map<string, any>();
32+
const x: Set<string[]> = new Set<any[]>();
33+
const x: Set<Set<Set<string>>> = new Set<Set<Set<any>>>();
34+
```
35+
36+
Examples of **correct** code for this rule:
37+
38+
```ts
39+
const x = 1,
40+
y = 1;
41+
const [x] = [1];
42+
[x] = [1] as [number];
43+
44+
function foo(a = 1) {}
45+
class Foo {
46+
constructor(private a = 1) {}
47+
}
48+
class Foo {
49+
private a = 1;
50+
}
51+
52+
// generic position examples
53+
const x: Set<string> = new Set<string>();
54+
const x: Map<string, string> = new Map<string, string>();
55+
const x: Set<string[]> = new Set<string[]>();
56+
const x: Set<Set<Set<string>>> = new Set<Set<Set<string>>>();
57+
```
58+
59+
## Related to
60+
61+
- [`no-explicit-any`](./no-explicit-any.md)
62+
- TSLint: [`no-unsafe-any`](https://palantir.github.io/tslint/rules/no-unsafe-any/)

packages/eslint-plugin/docs/rules/no-unsafe-call.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Disallows calling an any type value (`no-unsafe-call`)
22

33
Despite your best intentions, the `any` type can sometimes leak into your codebase.
4-
Member access on `any` typed variables is not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase.
4+
The arguments to, and return value of calling an `any` typed variable are not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase.
55

66
## Rule Details
77

packages/eslint-plugin/src/configs/all.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@typescript-eslint/no-unnecessary-qualifier": "error",
6464
"@typescript-eslint/no-unnecessary-type-arguments": "error",
6565
"@typescript-eslint/no-unnecessary-type-assertion": "error",
66+
"@typescript-eslint/no-unsafe-assignment": "error",
6667
"@typescript-eslint/no-unsafe-call": "error",
6768
"@typescript-eslint/no-unsafe-member-access": "error",
6869
"@typescript-eslint/no-unsafe-return": "error",

packages/eslint-plugin/src/rules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import noUnnecessaryCondition from './no-unnecessary-condition';
5555
import noUnnecessaryQualifier from './no-unnecessary-qualifier';
5656
import noUnnecessaryTypeArguments from './no-unnecessary-type-arguments';
5757
import noUnnecessaryTypeAssertion from './no-unnecessary-type-assertion';
58+
import noUnsafeAssignment from './no-unsafe-assignment';
5859
import noUnsafeCall from './no-unsafe-call';
5960
import noUnsafeMemberAccess from './no-unsafe-member-access';
6061
import noUnsafeReturn from './no-unsafe-return';
@@ -151,6 +152,7 @@ export default {
151152
'no-unnecessary-qualifier': noUnnecessaryQualifier,
152153
'no-unnecessary-type-arguments': noUnnecessaryTypeArguments,
153154
'no-unnecessary-type-assertion': noUnnecessaryTypeAssertion,
155+
'no-unsafe-assignment': noUnsafeAssignment,
154156
'no-unsafe-call': noUnsafeCall,
155157
'no-unsafe-member-access': noUnsafeMemberAccess,
156158
'no-unsafe-return': noUnsafeReturn,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy