or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-formatting.mdcode-quality-consistency.mdfunction-formatting.mdindex.mdline-breaks-newlines.mdmodern-javascript.mdobject-formatting.mdplugin-configuration.mdpunctuation-operators.mdspacing-indentation.md

code-quality-consistency.mddocs/

0

# Code Quality and Consistency

1

2

Rules that prevent common stylistic issues and enforce consistent patterns across codebases.

3

4

## no-extra-parens

5

6

Disallows unnecessary parentheses.

7

8

```javascript { .api }

9

const noExtraParens: Rule.RuleModule;

10

11

// Rule options

12

type NoExtraParensOptions =

13

| 'all'

14

| 'functions'

15

| ['all' | 'functions', {

16

conditionalAssign?: boolean;

17

returnAssign?: boolean;

18

nestedBinaryExpressions?: boolean;

19

ignoreJSX?: 'none' | 'all' | 'single-line' | 'multi-line';

20

enforceForArrowConditionals?: boolean;

21

enforceForSequenceExpressions?: boolean;

22

enforceForNewInMemberExpressions?: boolean;

23

enforceForFunctionPrototypeMethods?: boolean;

24

}];

25

```

26

27

**Usage Examples:**

28

29

```javascript

30

// ✗ Bad - unnecessary parentheses

31

const result = (a + b);

32

if ((condition)) {

33

doSomething();

34

}

35

const func = (function() { return true; });

36

37

// ✓ Good - necessary parentheses only

38

const result = a + b;

39

if (condition) {

40

doSomething();

41

}

42

const func = function() { return true; };

43

44

// ✓ Good - parentheses needed for precedence

45

const result = (a + b) * c;

46

const condition = (x === 1) || (y === 2);

47

48

// ✓ Good with { conditionalAssign: false }

49

let result;

50

if ((result = getValue())) { // parens allowed for assignment

51

process(result);

52

}

53

```

54

55

**Configuration:**

56

57

```javascript

58

rules: {

59

'@stylistic/js/no-extra-parens': ['error', 'all', { ignoreJSX: 'all' }]

60

}

61

```

62

63

## no-extra-semi

64

65

Disallows unnecessary semicolons.

66

67

```javascript { .api }

68

const noExtraSemi: Rule.RuleModule;

69

70

// No options

71

```

72

73

**Usage Examples:**

74

75

```javascript

76

// ✗ Bad - extra semicolons

77

function example() {

78

return true;;

79

}

80

81

const obj = {

82

name: 'John';

83

};

84

85

class Example {

86

method() {

87

return true;;

88

};

89

}

90

91

// ✓ Good - necessary semicolons only

92

function example() {

93

return true;

94

}

95

96

const obj = {

97

name: 'John'

98

};

99

100

class Example {

101

method() {

102

return true;

103

}

104

}

105

```

106

107

**Configuration:**

108

109

```javascript

110

rules: {

111

'@stylistic/js/no-extra-semi': 'error'

112

}

113

```

114

115

## no-mixed-spaces-and-tabs

116

117

Disallows mixed spaces and tabs for indentation.

118

119

```javascript { .api }

120

const noMixedSpacesAndTabs: Rule.RuleModule;

121

122

// Rule options

123

type NoMixedSpacesAndTabsOptions = 'smart-tabs' | boolean;

124

```

125

126

**Usage Examples:**

127

128

```javascript

129

// ✗ Bad - mixing spaces and tabs

130

function example() {

131

⇥ return true; // spaces followed by tab

132

}

133

134

// ✓ Good - consistent spaces

135

function example() {

136

return true;

137

}

138

139

// ✓ Good - consistent tabs

140

function example() {

141

⇥ return true;

142

}

143

144

// ✓ Good with "smart-tabs" - tabs for indentation, spaces for alignment

145

function example() {

146

⇥ const items = [

147

⇥ 'apple', // tab for indent, spaces for alignment

148

⇥ 'banana'

149

⇥ ];

150

}

151

```

152

153

**Configuration:**

154

155

```javascript

156

rules: {

157

'@stylistic/js/no-mixed-spaces-and-tabs': 'error'

158

}

159

```

160

161

## no-trailing-spaces

162

163

Disallows trailing whitespace at the end of lines.

164

165

```javascript { .api }

166

const noTrailingSpaces: Rule.RuleModule;

167

168

// Rule options

169

type NoTrailingSpacesOptions = {

170

skipBlankLines?: boolean;

171

ignoreComments?: boolean;

172

};

173

```

174

175

**Usage Examples:**

176

177

```javascript

178

// ✗ Bad - trailing spaces

179

const name = 'John';

180

const age = 30;

181

182

// ✓ Good - no trailing spaces

183

const name = 'John';

184

const age = 30;

185

186

// ✓ Good with skipBlankLines: true

187

const name = 'John';

188

// blank line with spaces OK

189

const age = 30;

190

191

// ✓ Good with ignoreComments: true

192

const name = 'John'; // comment with trailing spaces

193

```

194

195

**Configuration:**

196

197

```javascript

198

rules: {

199

'@stylistic/js/no-trailing-spaces': ['error', { skipBlankLines: true }]

200

}

201

```

202

203

## no-multi-spaces

204

205

Disallows multiple spaces.

206

207

```javascript { .api }

208

const noMultiSpaces: Rule.RuleModule;

209

210

// Rule options

211

type NoMultiSpacesOptions = {

212

exceptions?: {

213

[nodeType: string]: boolean;

214

};

215

ignoreEOLComments?: boolean;

216

};

217

```

218

219

**Usage Examples:**

220

221

```javascript

222

// ✗ Bad - multiple spaces

223

const name = 'John';

224

if (condition && other) {

225

doSomething();

226

}

227

228

// ✓ Good - single spaces

229

const name = 'John';

230

if (condition && other) {

231

doSomething();

232

}

233

234

// ✓ Good with exceptions: { Property: true }

235

const obj = {

236

name : 'John', // multiple spaces allowed in properties

237

age : 30

238

};

239

240

// ✓ Good with ignoreEOLComments: true

241

const value = 1; // multiple spaces before EOL comment OK

242

```

243

244

**Configuration:**

245

246

```javascript

247

rules: {

248

'@stylistic/js/no-multi-spaces': ['error', {

249

exceptions: { Property: true },

250

ignoreEOLComments: true

251

}]

252

}

253

```

254

255

## no-whitespace-before-property

256

257

Disallows whitespace before properties.

258

259

```javascript { .api }

260

const noWhitespaceBeforeProperty: Rule.RuleModule;

261

262

// No options

263

```

264

265

**Usage Examples:**

266

267

```javascript

268

// ✗ Bad - whitespace before property

269

const value = obj .property;

270

const result = user ['name'];

271

const method = obj .method();

272

273

// ✓ Good - no whitespace before property

274

const value = obj.property;

275

const result = user['name'];

276

const method = obj.method();

277

278

// Computed properties and method calls

279

const dynamic = obj[key];

280

const chained = obj.method().property;

281

```

282

283

**Configuration:**

284

285

```javascript

286

rules: {

287

'@stylistic/js/no-whitespace-before-property': 'error'

288

}

289

```

290

291

## max-len

292

293

Enforces a maximum line length.

294

295

```javascript { .api }

296

const maxLen: Rule.RuleModule;

297

298

// Rule options

299

type MaxLenOptions =

300

| number

301

| {

302

code?: number;

303

tabWidth?: number;

304

comments?: number;

305

ignorePattern?: string;

306

ignoreComments?: boolean;

307

ignoreTrailingComments?: boolean;

308

ignoreUrls?: boolean;

309

ignoreStrings?: boolean;

310

ignoreTemplateLiterals?: boolean;

311

ignoreRegExpLiterals?: boolean;

312

};

313

```

314

315

**Usage Examples:**

316

317

```javascript

318

// ✗ Bad with code: 80

319

const veryLongVariableNameThatExceedsTheMaximumLineLengthAndShouldBeWrapped = 'value';

320

321

// ✓ Good with code: 80

322

const longVariableName = 'value';

323

const message = 'This is a shorter line that fits within the limit';

324

325

// ✓ Good with ignoreUrls: true

326

const url = 'https://this-is-a-very-long-url-that-would-normally-exceed-the-line-length-limit.com/path'; // URL ignored

327

328

// ✓ Good with ignoreStrings: true

329

const longString = 'This is a very long string that would normally exceed the line length limit but is ignored'; // String ignored

330

```

331

332

**Configuration:**

333

334

```javascript

335

rules: {

336

'@stylistic/js/max-len': ['error', {

337

code: 100,

338

tabWidth: 2,

339

ignoreUrls: true,

340

ignoreStrings: true,

341

ignoreTemplateLiterals: true

342

}]

343

}

344

```

345

346

## max-statements-per-line

347

348

Enforces a maximum number of statements allowed per line.

349

350

```javascript { .api }

351

const maxStatementsPerLine: Rule.RuleModule;

352

353

// Rule options

354

type MaxStatementsPerLineOptions = {

355

max?: number;

356

};

357

```

358

359

**Usage Examples:**

360

361

```javascript

362

// ✗ Bad with max: 1 (default)

363

const a = 1; const b = 2;

364

if (condition) doSomething(); return;

365

366

// ✓ Good with max: 1

367

const a = 1;

368

const b = 2;

369

if (condition) {

370

doSomething();

371

}

372

return;

373

374

// ✓ Good with max: 2

375

const a = 1; const b = 2; // two statements OK

376

```

377

378

**Configuration:**

379

380

```javascript

381

rules: {

382

'@stylistic/js/max-statements-per-line': ['error', { max: 1 }]

383

}

384

```

385

386

## no-floating-decimal

387

388

Disallows leading or trailing decimal points in numeric literals.

389

390

```javascript { .api }

391

const noFloatingDecimal: Rule.RuleModule;

392

393

// No options

394

```

395

396

**Usage Examples:**

397

398

```javascript

399

// ✗ Bad - floating decimal points

400

const leading = .5;

401

const trailing = 2.;

402

403

// ✓ Good - complete decimal numbers

404

const leading = 0.5;

405

const trailing = 2.0;

406

const integer = 2;

407

const decimal = 1.5;

408

```

409

410

**Configuration:**

411

412

```javascript

413

rules: {

414

'@stylistic/js/no-floating-decimal': 'error'

415

}

416

```

417

418

## brace-style

419

420

Enforces consistent brace style for blocks.

421

422

```javascript { .api }

423

const braceStyle: Rule.RuleModule;

424

425

// Rule options

426

type BraceStyleOptions =

427

| '1tbs'

428

| 'stroustrup'

429

| 'allman'

430

| ['1tbs' | 'stroustrup' | 'allman', {

431

allowSingleLine?: boolean;

432

}];

433

```

434

435

**Usage Examples:**

436

437

```javascript

438

// ✓ Good with "1tbs" (default - One True Brace Style)

439

if (condition) {

440

doSomething();

441

} else {

442

doSomethingElse();

443

}

444

445

// ✓ Good with "stroustrup"

446

if (condition) {

447

doSomething();

448

}

449

else {

450

doSomethingElse();

451

}

452

453

// ✓ Good with "allman"

454

if (condition)

455

{

456

doSomething();

457

}

458

else

459

{

460

doSomethingElse();

461

}

462

463

// ✓ Good with allowSingleLine: true

464

if (condition) { doSomething(); }

465

```

466

467

**Configuration:**

468

469

```javascript

470

rules: {

471

'@stylistic/js/brace-style': ['error', '1tbs', { allowSingleLine: true }]

472

}

473

```

474

475

## Common Quality Combinations

476

477

### Strict Quality Rules

478

```javascript

479

rules: {

480

'@stylistic/js/no-extra-parens': ['error', 'all'],

481

'@stylistic/js/no-extra-semi': 'error',

482

'@stylistic/js/no-trailing-spaces': 'error',

483

'@stylistic/js/no-multi-spaces': 'error',

484

'@stylistic/js/max-len': ['error', { code: 80 }],

485

'@stylistic/js/max-statements-per-line': ['error', { max: 1 }]

486

}

487

```

488

489

### Relaxed Quality Rules

490

```javascript

491

rules: {

492

'@stylistic/js/no-extra-semi': 'error',

493

'@stylistic/js/no-trailing-spaces': ['error', { skipBlankLines: true }],

494

'@stylistic/js/no-multi-spaces': ['error', { ignoreEOLComments: true }],

495

'@stylistic/js/max-len': ['error', {

496

code: 120,

497

ignoreUrls: true,

498

ignoreStrings: true

499

}],

500

'@stylistic/js/brace-style': ['error', '1tbs', { allowSingleLine: true }]

501

}

502

```

503

504

## no-mixed-operators

505

506

Disallows mixed binary operators.

507

508

```javascript { .api }

509

const noMixedOperators: Rule.RuleModule;

510

511

// Rule options

512

type NoMixedOperatorsOptions = {

513

groups?: string[][];

514

allowSamePrecedence?: boolean;

515

};

516

```

517

518

**Usage Examples:**

519

520

```javascript

521

// ✗ Bad - mixed operators without parentheses

522

const result = a + b * c;

523

const condition = x && y || z;

524

525

// ✓ Good - use parentheses to clarify precedence

526

const result = a + (b * c);

527

const condition = (x && y) || z;

528

529

// ✓ Good - same operator

530

const sum = a + b + c;

531

const product = x * y * z;

532

533

// ✓ Good with allowSamePrecedence: true

534

const mixed = a * b / c; // same precedence operators OK

535

```

536

537

**Configuration:**

538

539

```javascript

540

rules: {

541

'@stylistic/js/no-mixed-operators': ['error', {

542

groups: [

543

['+', '-', '*', '/', '%', '**'],

544

['&', '|', '^', '~', '<<', '>>', '>>>'],

545

['==', '!=', '===', '!==', '>', '>=', '<', '<='],

546

['&&', '||'],

547

['in', 'instanceof']

548

],

549

allowSamePrecedence: true

550

}]

551

}

552

```

553

554

## wrap-iife

555

556

Requires parentheses around immediate function invocations.

557

558

```javascript { .api }

559

const wrapIife: Rule.RuleModule;

560

561

// Rule options

562

type WrapIifeOptions =

563

| 'outside'

564

| 'inside'

565

| 'any'

566

| ['outside' | 'inside' | 'any', {

567

functionPrototypeMethods?: boolean;

568

}];

569

```

570

571

**Usage Examples:**

572

573

```javascript

574

// ✓ Good with "outside" (default)

575

(function() {

576

console.log('IIFE');

577

})();

578

579

// ✓ Good with "inside"

580

(function() {

581

console.log('IIFE');

582

}());

583

584

// ✓ Good with "any"

585

(function() { console.log('IIFE'); })(); // either style OK

586

(function() { console.log('IIFE'); }());

587

588

// ✓ Good with functionPrototypeMethods: true

589

(function() {}.call(this)); // method calls wrapped

590

```

591

592

**Configuration:**

593

594

```javascript

595

rules: {

596

'@stylistic/js/wrap-iife': ['error', 'outside', {

597

functionPrototypeMethods: true

598

}]

599

}

600

```

601

602

## wrap-regex

603

604

Requires parenthesis around regex literals.

605

606

```javascript { .api }

607

const wrapRegex: Rule.RuleModule;

608

609

// No options

610

```

611

612

**Usage Examples:**

613

614

```javascript

615

// ✗ Bad - regex without parentheses

616

const result = /abc/.test(str);

617

618

// ✓ Good - regex wrapped in parentheses

619

const result = (/abc/).test(str);

620

621

// Assignment doesn't require wrapping

622

const pattern = /abc/;

623

const result = pattern.test(str);

624

```

625

626

**Configuration:**

627

628

```javascript

629

rules: {

630

'@stylistic/js/wrap-regex': 'error'

631

}

632

```

633

634

## Type Definitions

635

636

```typescript { .api }

637

interface QualityRules {

638

'no-extra-parens': Rule.RuleModule;

639

'no-extra-semi': Rule.RuleModule;

640

'no-mixed-spaces-and-tabs': Rule.RuleModule;

641

'no-trailing-spaces': Rule.RuleModule;

642

'no-multi-spaces': Rule.RuleModule;

643

'no-whitespace-before-property': Rule.RuleModule;

644

'max-len': Rule.RuleModule;

645

'max-statements-per-line': Rule.RuleModule;

646

'no-floating-decimal': Rule.RuleModule;

647

'brace-style': Rule.RuleModule;

648

'no-mixed-operators': Rule.RuleModule;

649

'wrap-iife': Rule.RuleModule;

650

'wrap-regex': Rule.RuleModule;

651

}

652

653

interface MaxLenConfig {

654

code?: number;

655

tabWidth?: number;

656

comments?: number;

657

ignorePattern?: string;

658

ignoreComments?: boolean;

659

ignoreTrailingComments?: boolean;

660

ignoreUrls?: boolean;

661

ignoreStrings?: boolean;

662

ignoreTemplateLiterals?: boolean;

663

ignoreRegExpLiterals?: boolean;

664

}

665

666

interface NoExtraParensConfig {

667

conditionalAssign?: boolean;

668

returnAssign?: boolean;

669

nestedBinaryExpressions?: boolean;

670

ignoreJSX?: 'none' | 'all' | 'single-line' | 'multi-line';

671

enforceForArrowConditionals?: boolean;

672

enforceForSequenceExpressions?: boolean;

673

enforceForNewInMemberExpressions?: boolean;

674

enforceForFunctionPrototypeMethods?: boolean;

675

}

676

```