Skip to content
beginner Phase 15 · TypeScript Testing & Tools

ESLint & Prettier (Advanced)

Enforce code quality with ESLint rules and format with Prettier.

30m
0 problems
Topic Progress 0%

Flat Config and Type-Aware Rules

Flat Config and Type-Aware Rules

ESLint 9 defaults to eslint.config.js, an array of flat objects; typescript-eslint composes them:

import tseslint from "typescript-eslint";

export default tseslint.config(
  { ignores: ["dist", "coverage"] },
  ...tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname },
    },
    rules: { "@typescript-eslint/no-unsafe-argument": "error" },
  },
);

Type-aware rules read the real type graph, which is how no-floating-promises catches an unawaited promise and no-unsafe-argument flags any flowing into a typed parameter — checks a syntax-only parser cannot make.

Prettier Without Friction

Prettier Without Friction

ESLint finds problems; Prettier formats. Running both on style rules causes flip-flop diffs, so the integration is a conflict disabler:

import prettier from "eslint-config-prettier";

export default tseslint.config(
  ...tseslint.configs.recommended,
  prettier,   // last: turns off formatting rules Prettier owns
);

eslint-config-prettier only switches conflicting rules off. The older eslint-plugin-prettier approach — running Prettier inside ESLint as a rule — reports formatting as lint errors and doubles run time; prefer prettier --write as its own script, with an editor formatter on save so both tools see the same code.

Pitfalls and Interview Angles

Pitfalls and Interview Angles

Speed. Type-aware linting builds a program per project; projectService reuses TypeScript's own service instead of per-run project globs, and ignoring dist keeps work bounded. Splitting a monorepo into per-package configs lets CI lint changed packages only.

Disabling rules. Prefer targeted eslint-disable-next-line with a reason over config-wide off; blanket disables hide the exact bugs the rules exist to catch.

Drift. Same ESLint version, same config, same files in editor and CI — pin the version and run eslint . rather than IDE-on-save only.

Interview: explain what type-aware linting trades (time, a valid tsconfig) for capability (promise and unsafe-any rules), and where it must sit in a pipeline.

Quiz

1. What does eslint-config-prettier actually change?

Question 1 options

2. Which rule requires type information to work?

Question 2 options

3. Why put prettier last in the flat config array?

Question 3 options

Flashcards

Question

Flat config

Answer

ESLint 9's eslint.config.js array of objects; later entries override earlier rules.

Question

Type-aware linting

Answer

Rules that query the TS type graph — enables no-floating-promises and no-unsafe-argument.

Question

projectService

Answer

typescript-eslint option reusing TypeScript's project service so config and speed improve.

Question

eslint-config-prettier

Answer

Disables conflicting stylistic rules; it does not format anything itself.

Revision Notes

Key Takeaways

  • 1. Type-aware rules are the reason to run ESLint on TypeScript at all
  • 2. Let Prettier own formatting; ESLint owns correctness
  • 3. Pin versions and run the same command in editor and CI

Interview Tips

  • • Name a bug only type-aware linting catches, and explain the cost it adds
  • • Defend why eslint-plugin-prettier-as-a-rule was abandoned in practice

Cheat Sheet

ESLint 9 flat config + tseslint recommendedTypeChecked, projectService:true; eslint-config-prettier last; prettier --write separately; lint dist ignored.

Continue Learning