Have ideas to improve npm?Join in the discussion! »

    @rushstack/eslint-plugin
    TypeScript icon, indicating that this package has built-in type declarations

    0.7.3 • Public • Published

    @rushstack/eslint-plugin

    This plugin implements supplementary rules for use with the @rushstack/eslint-config package, which provides a TypeScript ESLint ruleset tailored for large teams and projects. Please see that project's documentation for details. To learn about Rush Stack, please visit: https://rushstack.io/

    @rushstack/hoist-jest-mock

    Require Jest module mocking APIs to be called before any other statements in their code block.

    Rule Details

    Jest module mocking APIs such as "jest.mock()" must be called before the associated module is imported, otherwise they will have no effect. Transpilers such as ts-jest and babel-jest automatically "hoist" these calls, however this can produce counterintuitive behavior. Instead, the hoist-jest-mocks lint rule simply requires developers to write the statements in the correct order.

    The following APIs are affected: 'jest.mock()', 'jest.unmock()', 'jest.enableAutomock()', 'jest.disableAutomock()', 'jest.deepUnmock()'.

    For technical background, please read the Jest documentation here: https://jestjs.io/docs/en/es6-class-mocks

    Examples

    The following patterns are considered problems when @rushstack/hoist-jest-mock is enabled:

    import * as file from './file'; // import statement
    jest.mock('./file'); // error
    
    test("example", () => {
      jest.mock('./file2'); // error
    });
    require('./file'); // import statement
    jest.mock('./file'); // error

    The following patterns are NOT considered problems:

    jest.mock('./file'); // okay, because mock() precedes the import below
    import * as file from './file'; // import statement
    // These statements are not real "imports" because they import compile-time types
    // without any runtime effects
    import type { X } from './file';
    let y: typeof import('./file');
    
    jest.mock('./file'); // okay

    @rushstack/no-new-null

    Prevent usage of the JavaScript null value, while allowing code to access existing APIs that may require null.

    Rule Details

    Most programming languages have a "null" or "nil" value that serves several purposes:

    1. the initial value for an uninitialized variable
    2. the value of x.y or x["y"] when x has no such key, and
    3. a special token that developers can assign to indicate an unknown or empty state.

    In JavaScript, the undefined value fulfills all three roles. JavaScript's null value is a redundant secondary token that only fulfills (3), even though its name confusingly implies otherwise. The null value was arguably a mistake in the original JavaScript language design, but it cannot be banned entirely because it is returned by some entrenched system APIs such as JSON.parse(), and also some popular NPM packages. Thus, this rule aims to tolerate preexisting null values while preventing new ones from being introduced.

    The @rushstack/no-new-null rule flags type definitions with null that can be exported or used by others. The rule ignores declarations that are local variables, private members, or types that are not exported.

    If you are designing a new JSON file format, it's a good idea to avoid null entirely. In most cases there are better representations that convey more information about an item that is unknown, omitted, or disabled. If you do need to declare types for JSON structures containing null, rather than suppressing the lint rule, you can use a specialized JsonNull type as provided by @rushstack/node-core-library.

    Examples

    The following patterns are considered problems when @rushstack/no-new-null is enabled:

    // interface declaration with null field
    interface IHello { hello: null; } // error
    
    // type declaration with null field
    type Hello = { hello: null; } // error
    
    // type function alias
    type T = (args: string | null) => void; // error
    
    // type alias
    type N = null; // error
    
    // type constructor
    type C = {new (args: string | null)} // error
    
    // function declaration with null args
    function hello(world: string | null): void {}; // error
    function legacy(callback: (err: Error| null) => void): void { }; // error
    
    // function with null return type
    function hello(): (err: Error | null) => void {}; // error
    
    // const with null type
    const nullType: 'hello' | null = 'hello'; // error
    
    // classes with publicly visible properties and methods
    class PublicNulls {
      property: string | null; // error
      propertyFunc: (val: string | null) => void; // error
      legacyImplicitPublic(hello: string | null): void {} // error
      public legacyExplicitPublic(hello: string | null): void {} // error
    }

    The following patterns are NOT considered problems:

    // wrapping an null-API
    export function ok(hello: string): void {
      const innerCallback: (err: Error | null) => void = (e) => {}; // passes
      return innerCallback(null);
    }
    
    // classes where null APIs are used, but are private-only
    class PrivateNulls {
      private pField: string | null; // passes
      private pFunc: (val: string | null) => void; // passes
      private legacyPrivate(hello: string | null): void { // passes
        this.pField = hello;
        this.pFunc(this.pField)
        this.pFunc('hello')
      }
    }

    @rushstack/no-null

    (Deprecated) Prevent usage of JavaScript's null keyword.

    Rule Details

    This rule has been superseded by @rushstack/no-new-null, and is maintained to support code that has not migrated to the new rule yet. The @rushstack/no-null rule prohibits null as a literal value, but allows it in type annotations. Comparisons with null are also allowed.

    Examples

    The following patterns are considered problems when @rushstack/no-null is enabled:

    let x = null;  // error
    
    f(null); // error
    
    function g() {
        return null; // error
    }

    The following patterns are NOT considered problems:

    let x: number | null = f(); // declaring types as possibly "null" is okay
    
    if (x === null) {  // comparisons are okay
        x = 0;
    }

    @rushstack/no-untyped-underscore (Opt-in)

    Prevent TypeScript code from accessing legacy JavaScript members whose name has an underscore prefix.

    Rule Details

    JavaScript does not provide a straightforward way to restrict access to object members, so API names commonly indicate a private member by using an underscore prefix (e.g. exampleObject._privateMember). For inexperienced developers who may be unfamiliar with this convention, in TypeScript we can mark the APIs as private or omit them from the typings. However, when migrating a large code base to TypeScript, it may be difficult to declare types for every legacy API. In this situation, the @rushstack/no-untyped-underscore rule can help.

    This rule detects expressions that access a member with an underscore prefix, EXCEPT in cases where:

    • The object is typed: specifically, exampleObject has a TypeScript type that declares _privateMember; OR
    • The object expression uses: the this or super keywords; OR
    • The object expression is a variable named that. (In older ES5 code, that was commonly used as an alias for this in unbound contexts.)

    Examples

    The following patterns are considered problems when @rushstack/no-untyped-underscore is enabled:

    let x: any;
    x._privateMember = 123;  // error, because x is untyped
    
    let x: { [key: string]: number };
    x._privateMember = 123;  // error, because _privateMember is not a declared member of x's type

    The following patterns are NOT considered problems:

    let x: { _privateMember: any };
    x._privateMember = 123;  // okay, because _privateMember is declared by x's type
    
    let x = { _privateMember: 0 };
    x._privateMember = 123;  // okay, because _privateMember is part of the inferred type
    
    enum E {
        _PrivateMember
    }
    let e: E._PrivateMember = E._PrivateMember; // okay, because _PrivateMember is declared by E

    Links

    @rushstack/eslint-plugin is part of the Rush Stack family of projects.

    Install

    npm i @rushstack/eslint-plugin

    DownloadsWeekly Downloads

    15,208

    Version

    0.7.3

    License

    MIT

    Unpacked Size

    104 kB

    Total Files

    42

    Homepage

    rushstack.io

    Last publish

    Collaborators

    • avatar
    • avatar