practical-tslint-config
v1.0.8
Published
A TSLint ruleset based on the Airbnb style guide, Prettier, and practicality
Downloads
3
Maintainers
Readme
A TSLint ruleset based on the Airbnb JavaScript style guide, Prettier, and TypeScript best practices.
Goal
To build a ruleset that promotes consistency, efficiency, optimized code, and most of all to not get in the developer's way.
Installation
npm install practical-tslint-config --save-dev
Usage
The only thing that your tslint.json
should consist of:
{
"extends": "practical-tslint-config"
}
Some of the rules in the set require type info. Therefore when you run the linter via CLI,
specifying the --project
flag is recommended.
tslint --project tsconfig.json --config tslint.json
Prettier
This ruleset is specifically designed to not lint for any rules that you can set (and automatically fix) through Prettier. Therefore it is highly recommended that you configure Prettier for your project with this custom configuration.
npm install prettier prettier-airbnb-config --save-dev
Custom Rules
The Airbnb JavaScript style guide does an excellent job of being a mostly reasonable guide to JavaScript. However, linting rules don't exist for every recommendation in the style guide nor do they capture all of TypeScript's nuances. Furthermore, a fair number of rules can be fixed using Prettier. Therefore the other rules that this configuration lints for that aren't outlined in the Airbnb guide are mentioned here.
Imports
c1.1 Requires that import statements be alphabetized and grouped.
// bad import {bar, foo} from '../zxy'; import Abc from '../Xyz'; // good import Abc from '../Xyz'; import {bar, foo} from '../zxy';
Variables
- c2.1 Variables initialized with
let
or destructuring initializer should not be assigned toundefined
.
Values in JavaScript default to undefined. There’s no need to do so manually.
// bad
let a = undefined;
// good
let a;
c2.2 Disallows shadowing variable declarations.
When a variable in a local scope and a variable in the containing scope have the same name, shadowing occurs. Shadowing makes it impossible to access the variable in the containing scope and obscures to what value an identifier actually refers.
// bad const a = 'no shadow'; function print() { const a = 'shadow'; // TSLint will complain here. console.log(a); } print(); // logs 'shadow'. // good const a = 'no shadow'; function print() { console.log(a); } print(); // logs 'no shadow'.
Classes
c3.1 Requires explicit visibility declarations for class members.
Members lacking a visibility declaration may be an indication of an accidental leak of class internals.
// bad class Foo { bar: string; } // good class Foo { private bar: string; }
c3.2 Enforces member ordering.
A consistent ordering for class members can make classes easier to read, navigate, and edit.
// bad class Foo { public bar() { ... } private abc: string; public static xyz: boolean; } // good class Foo { public static xyz: boolean; private abc: string; public bar() { ... } }
c3.3 Warns if
super()
appears twice in a constructor.The second call to
super()
will fail at runtime.// bad class Foo extends Bar { public constructor() { super(); super(); } } // good class Foo extends Bar { public constructor() { super(); } }
Interfaces
c4.1 Forbids empty interfaces.
// bad interface Foo {} // good interface Foo { foo: string; }
c4.2 Requires interface names to not have an “I” prefix
// bad interface IFoo {} // good interface Foo { foo: string; }
Functions
c5.1 Disallows empty blocks.
Empty blocks are often indicators of missing code.
// bad function foo() {} // good function foo() { if (conditional) { ... } }
Maintainability
c6.1 Disallows use of the
null
keyword literal.To remove confusion over the two similar values, it’s better to stick with just
undefined
.// bad let a: string | null; // good let a: string | undefined;
c6.2 Disallows non-null assertions using the
!
postfix operator.Using non-null assertion cancels the benefits of the strict null checking mode.
// bad function foo(instance: MyClass | undefined) { instance!.doWork(); } // good function foo(instance: MyClass | undefined) { if (instance !== undefined) { instance.doWork(); } }