TypeScript Linting & Prettier — Complete Guide
In this tutorial, you will learn about TypeScript Linting & Prettier. We cover key concepts, practical examples, and best practices to help you master this topic.
TypeScript linting with ESLint and the @typescript-eslint plugin catches logic errors, enforces code style, and prevents common TypeScript-specific pitfalls through hundreds of configurable rules that integrate seamlessly into your editor and CI pipeline.
What You'll Learn
- Setting up ESLint for TypeScript
- @typescript-eslint recommended rules
- Integrating Prettier for formatting
- Editor integration and auto-fix
- Custom rule configuration
Why It Matters
TypeScript catches type errors. ESLint catches logic, style, and best-practice errors. Together, they provide comprehensive code quality enforcement. Without linting, codebases drift into inconsistent styles and subtle bugs.
Real-World Use
DodaTech's TypeScript monorepo has strict ESLint rules enforced in CI. A custom rule prevents importing from shared internals (only public exports allowed). Another rule enforces error handling in async functions. These rules have prevented dozens of production incidents.
Learning Path
flowchart LR A[Source Maps] --> B[Linting] B --> C[Bundling] B --> D[You Are Here] C --> E[React Components] E --> F[React Hooks]
Installing ESLint for TypeScript
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
Configuration
// eslint.config.js (flat config, ESLint 9+)
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';
export default [
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parser: tsparser,
parserOptions: {
project: './tsconfig.json',
},
},
plugins: {
'@typescript-eslint': tseslint,
},
rules: {
...tseslint.configs.recommended.rules,
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/explicit-function-return-type': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/consistent-type-imports': 'error',
},
},
];
Key @typescript-eslint Rules
Error Prevention
| Rule | Purpose |
|---|---|
no-explicit-any |
Warn on any type usage |
no-floating-promises |
Require awaiting or handling promises |
no-misused-promises |
Prevent promises in wrong contexts |
strict-boolean-expressions |
Require strict boolean conditions |
no-unnecessary-type-assertion |
Prevent redundant as casts |
Style & Consistency
| Rule | Purpose |
|---|---|
consistent-type-imports |
Enforce import type for type-only imports |
consistent-type-definitions |
Prefer interface or type consistently |
explicit-function-return-type |
Require return type annotations |
explicit-member-accessibility |
Require public/private/protected |
member-ordering |
Enforce member ordering in classes |
TypeScript-Specific
| Rule | Purpose |
|------|---------|
| prefer-readonly | Mark never-modified properties as readonly |
| prefer-nullish-coalescing | Prefer ?? over || for null checks |
| prefer-optional-chain | Prefer ?. over && for optional access |
| unified-signatures | Combine overloads where possible |
Integrating Prettier
Prettier handles formatting (spaces, semicolons, quotes). ESLint handles logic (unused variables, promise handling).
npm install --save-dev prettier eslint-config-prettier
// eslint.config.js (add to rules)
{
rules: {
...tseslint.configs.recommended.rules,
...require('eslint-config-prettier').rules, // Disables conflicting ESLint rules
},
}
// .prettierrc
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"arrowParens": "always"
}
Editor Integration
VS Code
Install extensions: ESLint, Prettier.
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"eslint.validate": ["typescript", "typescriptreact"],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}
Running in CI
// package.json
{
"scripts": {
"lint": "eslint 'src/**/*.{ts,tsx}'",
"lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix",
"format": "prettier --write 'src/**/*.{ts,tsx}'",
"format:check": "prettier --check 'src/**/*.{ts,tsx}'"
}
}
Custom Rules
Create project-specific rules:
// eslint-local-rules/index.js
module.exports = {
'no-console-log': {
meta: { type: 'suggestion' },
create(context) {
return {
CallExpression(node) {
if (node.callee.object?.name === 'console' && node.callee.property?.name === 'log') {
context.report({ node, message: 'Use logger instead of console.log' });
}
},
};
},
},
};
Common Mistakes
1. Disabling ESLint for Type-Specific Files
Avoid /* eslint-disable */ at the top of files. Instead fix the underlying issues or use targeted disable comments.
2. Not Running ESLint in CI
If linting isn't enforced, rules will be ignored under deadline pressure.
3. Conflicting ESLint and Prettier Rules
Use eslint-config-prettier to disable formatting rules that conflict with Prettier.
4. Using @typescript-eslint/recommended Without Thought
Review each rule before enabling. Some may be too strict for your project.
5. Not Using parserOptions.project
Without pointing to tsconfig.json, rules requiring type information (like no-floating-promises) won't work.
Practice Questions
What is the difference between ESLint and Prettier? ESLint catches logic errors and enforces code practices. Prettier handles formatting (spacing, semicolons, quotes).
Why do you need
@typescript-eslint/parser? Standard ESLint cannot parse TypeScript syntax. The parser converts TypeScript to an AST ESLint can understand.What does
no-floating-promisesdo? Errors when promises are not awaited or have no.catch()handler.How do you auto-fix ESLint errors on save in VS Code? Configure
editor.codeActionsOnSavewith"source.fixAll.eslint": "explicit".
Challenge: Set up an ESLint configuration for a TypeScript React project that enforces import type for type-only imports, warns on any, and requires explicit return types on functions.
FAQ
Mini Project: Lint Setup Script
npm init -y
npm install --save-dev typescript eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-config-prettier
// eslint.config.js
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';
export default [
{
files: ['src/**/*.ts'],
languageOptions: { parser: tsparser },
plugins: { '@typescript-eslint': tseslint },
rules: {
...tseslint.configs.recommended.rules,
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/explicit-function-return-type': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/consistent-type-imports': 'error',
semi: 'error',
'no-console': 'warn',
},
},
];
What's Next
Now explore Bundling TypeScript for production:
| Lesson | Description |
|---|---|
| {{< ref "/programming-languages/typescript/34-source-maps-debugging" >}} | Review source maps |
| {{< ref "/programming-languages/typescript/36-bundling" >}} | Vite, Webpack, Esbuild, tsup |
| {{< ref "/programming-languages/typescript/37-react-components" >}} | React with TypeScript |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro