ESLint


ESLint is the JavaScript linter. You may be familiar with it from SEEK’s frontend development toolkit, sku.

If you’re coming from your own bespoke backend configuration or @seek/seek-module-toolkit, you may have been using TSLint. TSLint has been out of support since December 2020.

Our ESLint configuration introduces stricter rules around unsafe type usage.


Extend configuration

Please contribute to the eslint-config-seek preset if you feel something is missing! It may worthwhile starting with a discussion in #typescriptification to garner feedback.

If you wish to enforce additional rules within a given codebase or team, you can extend your .eslintrc.js:

module.exports = {
  extends: ['skuba'],
  rules: {
    // https://eslint.org/docs/rules/complexity
    complexity: ['error', { max: 3 }],
  },
};

Let’s check that our new rule has taken effect. Craft some absolute nonsense in a source file:

export const evilFn = () => {
  if (NaN) {
    if (NaN) {
      if (NaN) {
      }
    }
  }
};

You should see some red squigglies!

Arrow function has a complexity of 4. Maximum allowed is 3. eslint(complexity)

Avoid any and object

Our ESLint rules flag unsound type usage that may cause unexpected runtime behaviour or crashes.

Consider the following alternatives:

  1. Use unknown for a value whose type is truly unknown. This is a type-safe alternative to any that the TypeScript ecosystem is moving towards.

    - const data = JSON.parse(str);
    + const data = JSON.parse(str) as unknown;
    
  2. Prove the value has a specific type using a type guard or runtime validation library.

    - const safeData = inputData as any;
    + const safeData = RuntimeValidator.check(inputData);
    
  3. Use Record<PropertyKey, unknown> to indicate an object with unknown properties.

    - const isObject = (data: unknown): data is object => { ... };
    + const isObject = (data: unknown): data is Record<PropertyKey, unknown> => { ... };
    
  4. Disable the specific ESLint rule for the problematic line.

    /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */
    const takeAnyBody = ctx.request.body;