0
# Type Safety Rules
1
2
Rules focused on TypeScript type safety, preventing common type-related errors and enforcing proper type usage. These rules leverage TypeScript's type system to catch potential runtime errors at build time.
3
4
## Capabilities
5
6
### Unsafe Type Operations
7
8
Rules that prevent operations on `any` types and other unsafe type interactions.
9
10
```typescript { .api }
11
/**
12
* Disallow assigning any values to variables and properties
13
*/
14
"no-unsafe-assignment": RuleModule;
15
16
/**
17
* Disallow calling any typed value
18
*/
19
"no-unsafe-call": RuleModule;
20
21
/**
22
* Disallow member access on any typed variables
23
*/
24
"no-unsafe-member-access": RuleModule;
25
26
/**
27
* Disallow returning any from a function
28
*/
29
"no-unsafe-return": RuleModule;
30
31
/**
32
* Disallow calling a function with any type argument
33
*/
34
"no-unsafe-argument": RuleModule;
35
36
/**
37
* Disallow unsafe type assertions using any
38
*/
39
"no-unsafe-type-assertion": RuleModule;
40
41
/**
42
* Disallow unsafe function types
43
*/
44
"no-unsafe-function-type": RuleModule;
45
46
/**
47
* Disallow unsafe enum comparison
48
*/
49
"no-unsafe-enum-comparison": RuleModule;
50
51
/**
52
* Disallow unsafe declaration merging
53
*/
54
"no-unsafe-declaration-merging": RuleModule;
55
56
/**
57
* Disallow unsafe unary minus operator
58
*/
59
"no-unsafe-unary-minus": RuleModule;
60
61
/**
62
* Require .toString() to only be called on objects which provide useful information when stringified
63
*/
64
"no-base-to-string": RuleModule;
65
66
/**
67
* Disallow the any type
68
*/
69
"no-explicit-any": RuleModule;
70
71
/**
72
* Enforce valid definition of new and constructor
73
*/
74
"no-misused-new": RuleModule;
75
```
76
77
**Usage Examples:**
78
79
```typescript
80
// ❌ Bad - no-unsafe-assignment
81
let foo: number;
82
foo = bar as any; // Error: Unsafe assignment
83
84
// ✅ Good
85
let foo: number;
86
foo = bar as number; // Type assertion with proper type
87
88
// ❌ Bad - no-unsafe-call
89
declare const fn: any;
90
fn(); // Error: Unsafe call
91
92
// ✅ Good
93
declare const fn: () => void;
94
fn(); // Safe call with proper typing
95
```
96
97
### Promise and Async Safety
98
99
Rules that ensure proper handling of Promises and async operations.
100
101
```typescript { .api }
102
/**
103
* Require Promise-like values to be handled appropriately
104
*/
105
"no-floating-promises": RuleModule;
106
107
/**
108
* Disallow awaiting a value that is not a Thenable
109
*/
110
"await-thenable": RuleModule;
111
112
/**
113
* Disallow Promises in places not designed to handle them
114
*/
115
"no-misused-promises": RuleModule;
116
117
/**
118
* Enforce consistent returning of awaited values
119
*/
120
"return-await": RuleModule;
121
122
/**
123
* Require async functions to return a Promise
124
*/
125
"promise-function-async": RuleModule;
126
```
127
128
**Usage Examples:**
129
130
```typescript
131
// ❌ Bad - no-floating-promises
132
fetchData(); // Error: Promise not handled
133
134
// ✅ Good
135
await fetchData(); // Promise properly awaited
136
fetchData().catch(console.error); // Promise error handled
137
138
// ❌ Bad - await-thenable
139
await 42; // Error: Awaiting non-thenable
140
141
// ✅ Good
142
await Promise.resolve(42); // Awaiting actual Promise
143
144
// ❌ Bad - no-misused-promises
145
if (fetchData()) { // Error: Promise in boolean context
146
// ...
147
}
148
149
// ✅ Good
150
const result = await fetchData();
151
if (result) {
152
// ...
153
}
154
```
155
156
### Type Assertion Safety
157
158
Rules that govern the safe use of type assertions and non-null assertions.
159
160
```typescript { .api }
161
/**
162
* Disallow non-null assertions using the ! postfix operator
163
*/
164
"no-non-null-assertion": RuleModule;
165
166
/**
167
* Disallow extra non-null assertions
168
*/
169
"no-extra-non-null-assertion": RuleModule;
170
171
/**
172
* Disallow non-null assertion in left operand of nullish coalescing
173
*/
174
"no-non-null-asserted-nullish-coalescing": RuleModule;
175
176
/**
177
* Disallow non-null assertion in left operand of optional chaining
178
*/
179
"no-non-null-asserted-optional-chain": RuleModule;
180
181
/**
182
* Disallow confusing non-null assertion-like expressions
183
*/
184
"no-confusing-non-null-assertion": RuleModule;
185
186
/**
187
* Enforce consistent type assertions
188
*/
189
"consistent-type-assertions": RuleModule;
190
191
/**
192
* Disallow unnecessary type assertions
193
*/
194
"no-unnecessary-type-assertion": RuleModule;
195
```
196
197
**Usage Examples:**
198
199
```typescript
200
// ❌ Bad - no-non-null-assertion
201
const user = getUser()!; // Error: Non-null assertion
202
203
// ✅ Good
204
const user = getUser();
205
if (user) {
206
// Use user safely
207
}
208
209
// ❌ Bad - no-extra-non-null-assertion
210
const value = foo!!!.bar; // Error: Extra non-null assertions
211
212
// ✅ Good
213
const value = foo!.bar; // Single assertion if necessary
214
215
// ❌ Bad - no-non-null-asserted-nullish-coalescing
216
const value = foo! ?? 'default'; // Error: Non-null assertion with nullish coalescing
217
218
// ✅ Good
219
const value = foo ?? 'default'; // Just use nullish coalescing
220
```
221
222
### Type Checking and Validation
223
224
Rules that enforce proper type checking and validation patterns.
225
226
```typescript { .api }
227
/**
228
* Disallow unnecessary conditionals
229
*/
230
"no-unnecessary-condition": RuleModule;
231
232
/**
233
* Disallow unnecessary boolean literal compare
234
*/
235
"no-unnecessary-boolean-literal-compare": RuleModule;
236
237
/**
238
* Disallow unnecessary type arguments
239
*/
240
"no-unnecessary-type-arguments": RuleModule;
241
242
/**
243
* Disallow unnecessary type constraints
244
*/
245
"no-unnecessary-type-constraint": RuleModule;
246
247
/**
248
* Disallow unnecessary type parameters
249
*/
250
"no-unnecessary-type-parameters": RuleModule;
251
252
/**
253
* Disallow unnecessary type conversion
254
*/
255
"no-unnecessary-type-conversion": RuleModule;
256
257
/**
258
* Enforce template literal expressions to be of string type
259
*/
260
"restrict-template-expressions": RuleModule;
261
262
/**
263
* Require both operands of addition to have type number or string
264
*/
265
"restrict-plus-operands": RuleModule;
266
267
/**
268
* Enforce strict boolean expressions
269
*/
270
"strict-boolean-expressions": RuleModule;
271
272
/**
273
* Require switch-case statements to be exhaustive with union type
274
*/
275
"switch-exhaustiveness-check": RuleModule;
276
```
277
278
**Usage Examples:**
279
280
```typescript
281
// ❌ Bad - no-unnecessary-condition
282
const str: string = 'hello';
283
if (str) { // Error: Always truthy
284
// ...
285
}
286
287
// ✅ Good
288
if (str.length > 0) { // Meaningful condition
289
// ...
290
}
291
292
// ❌ Bad - restrict-plus-operands
293
const result = value + {}; // Error: Object in addition
294
295
// ✅ Good
296
const result = value + String(obj); // Explicit conversion
297
298
// ❌ Bad - strict-boolean-expressions
299
if (value) { // Error: Not explicitly boolean
300
// ...
301
}
302
303
// ✅ Good
304
if (value !== null && value !== undefined) {
305
// ...
306
}
307
308
// ❌ Bad - switch-exhaustiveness-check
309
type Color = 'red' | 'green' | 'blue';
310
function handleColor(color: Color) {
311
switch (color) {
312
case 'red':
313
return '#ff0000';
314
case 'green':
315
return '#00ff00';
316
// Error: Missing case for 'blue'
317
}
318
}
319
320
// ✅ Good
321
function handleColor(color: Color) {
322
switch (color) {
323
case 'red':
324
return '#ff0000';
325
case 'green':
326
return '#00ff00';
327
case 'blue':
328
return '#0000ff';
329
default:
330
return assertNever(color);
331
}
332
}
333
```
334
335
### Type Definition Safety
336
337
Rules that ensure safe usage of TypeScript type definitions and declarations.
338
339
```typescript { .api }
340
/**
341
* Disallow duplicate enum values
342
*/
343
"no-duplicate-enum-values": RuleModule;
344
345
/**
346
* Disallow duplicate type constituents
347
*/
348
"no-duplicate-type-constituents": RuleModule;
349
350
/**
351
* Disallow redundant type constituents
352
*/
353
"no-redundant-type-constituents": RuleModule;
354
355
/**
356
* Disallow empty interfaces
357
*/
358
"no-empty-interface": RuleModule;
359
360
/**
361
* Disallow empty object types
362
*/
363
"no-empty-object-type": RuleModule;
364
365
/**
366
* Disallow invalid void type usage
367
*/
368
"no-invalid-void-type": RuleModule;
369
370
/**
371
* Disallow wrapper object types
372
*/
373
"no-wrapper-object-types": RuleModule;
374
375
/**
376
* Disallow mixed enums
377
*/
378
"no-mixed-enums": RuleModule;
379
```
380
381
**Usage Examples:**
382
383
```typescript
384
// ❌ Bad - no-duplicate-enum-values
385
enum Direction {
386
Up = 1,
387
Down = 1, // Error: Duplicate value
388
Left = 2,
389
Right = 3
390
}
391
392
// ✅ Good
393
enum Direction {
394
Up = 1,
395
Down = 2,
396
Left = 3,
397
Right = 4
398
}
399
400
// ❌ Bad - no-empty-interface
401
interface EmptyInterface {} // Error: Empty interface
402
403
// ✅ Good
404
interface UserInterface {
405
name: string;
406
email: string;
407
}
408
409
// ❌ Bad - no-invalid-void-type
410
let value: void = undefined; // Error: Invalid void usage
411
412
// ✅ Good
413
function doSomething(): void {
414
// Function returning void
415
}
416
```
417
418
### Array and Iteration Safety
419
420
Rules that ensure safe operations on arrays and iterables.
421
422
```typescript { .api }
423
/**
424
* Disallow iterating over an array with a for-in loop
425
*/
426
"no-for-in-array": RuleModule;
427
428
/**
429
* Disallow spreading non-iterable types
430
*/
431
"no-misused-spread": RuleModule;
432
433
/**
434
* Require Array.from() over spreading non-arrays
435
*/
436
"prefer-for-of": RuleModule;
437
438
/**
439
* Require array-like objects to be converted with Array.from()
440
*/
441
"prefer-includes": RuleModule;
442
443
/**
444
* Require using the built-in comparison function in Array.sort()
445
*/
446
"require-array-sort-compare": RuleModule;
447
```
448
449
**Usage Examples:**
450
451
```typescript
452
// ❌ Bad - no-for-in-array
453
const arr = [1, 2, 3];
454
for (const key in arr) { // Error: for-in on array
455
console.log(arr[key]);
456
}
457
458
// ✅ Good
459
for (const item of arr) {
460
console.log(item);
461
}
462
463
// ❌ Bad - no-misused-spread
464
const notIterable = { a: 1, b: 2 };
465
const arr = [...notIterable]; // Error: Spreading non-iterable
466
467
// ✅ Good
468
const arr = Object.values(notIterable);
469
```
470
471
## Types
472
473
```typescript { .api }
474
interface RuleModule {
475
meta: {
476
type: "problem" | "suggestion" | "layout";
477
docs: {
478
description: string;
479
recommended?: boolean | string;
480
requiresTypeChecking?: boolean;
481
};
482
messages: Record<string, string>;
483
schema: JSONSchema;
484
};
485
create(context: RuleContext): RuleListener;
486
}
487
488
interface RuleContext {
489
id: string;
490
options: unknown[];
491
settings: Record<string, unknown>;
492
parserOptions: ParserOptions;
493
getSourceCode(): SourceCode;
494
report(descriptor: ReportDescriptor): void;
495
}
496
497
interface RuleListener {
498
[nodeType: string]: (node: Node) => void;
499
}
500
```