or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

best-practices-rules.mdcode-quality-rules.mdindex.mdplugin-configuration.mdstyle-formatting-rules.mdtype-safety-rules.md

type-safety-rules.mddocs/

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

```