Category: reference
ESLint + Prettier Configuration — TypeScript Project Setup
ตั้งค่า ESLint + Prettier ที่ทำงานร่วมกันได้สำหรับ TypeScript project: rules, integrations, pre-commit hooks
สารบัญ
Install
# ESLint + TypeScript support
npm install --save-dev eslint @eslint/js typescript-eslint
# Prettier + ESLint integration
npm install --save-dev prettier eslint-config-prettier
# Pre-commit hooks
npm install --save-dev lint-staged husky
ESLint Config (Flat Config — ESLint 9+)
// eslint.config.js
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
prettier, // ต้องอยู่ท้ายสุด — disable rules ที่ clash กับ Prettier
{
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
// TypeScript
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/no-floating-promises': 'error',
// General
'no-console': ['warn', { allow: ['warn', 'error'] }],
'prefer-const': 'error',
},
},
{
// ไม่ตรวจไฟล์เหล่านี้
ignores: ['dist/**', 'node_modules/**', '*.config.js', '*.config.ts'],
},
);
ESLint Flat Config (Legacy — ESLint 8)
// .eslintrc.cjs
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-type-checked',
'prettier', // ต้องอยู่ท้ายสุด
],
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'no-console': ['warn', { allow: ['warn', 'error'] }],
},
ignorePatterns: ['dist/', 'node_modules/'],
};
Prettier Config
// .prettierrc
{
"semi": true,
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf"
}
# .prettierignore
dist/
node_modules/
*.min.js
*.min.css
package-lock.json
Astro-specific Config
npm install --save-dev eslint-plugin-astro @typescript-eslint/parser
// eslint.config.js
import astro from 'eslint-plugin-astro';
export default tseslint.config(
...astro.configs.recommended,
{
files: ['**/*.astro'],
languageOptions: {
parser: astroParser,
parserOptions: { parser: '@typescript-eslint/parser' },
},
},
);
package.json Scripts
{
"scripts": {
"lint": "eslint src --ext .ts,.tsx,.astro",
"lint:fix": "eslint src --ext .ts,.tsx,.astro --fix",
"format": "prettier --write .",
"format:check": "prettier --check ."
}
}
Pre-commit Hooks ด้วย lint-staged + husky
# Setup husky
npx husky init
# เพิ่ม pre-commit hook
echo "npx lint-staged" > .husky/pre-commit
// package.json
{
"lint-staged": {
"*.{ts,tsx,astro}": ["eslint --fix", "prettier --write"],
"*.{css,json,md}": ["prettier --write"]
}
}
ทุกครั้งที่ git commit จะ lint + format เฉพาะไฟล์ที่ staged อัตโนมัติ
VS Code Integration
// .vscode/settings.json
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["javascript", "typescript", "astro"],
"[astro]": {
"editor.defaultFormatter": "astro-build.astro-vscode"
}
}
// .vscode/extensions.json
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"astro-build.astro-vscode"
]
}
Rules ที่ควรรู้
// Rules ที่ useful มาก
{
// ไม่ let ถ้าไม่มีการ reassign
'prefer-const': 'error',
// ห้ามใช้ == (ใช้ === เท่านั้น)
'eqeqeq': ['error', 'always'],
// ไม่ return await ใน async function (ยกเว้น try/catch)
'@typescript-eslint/return-await': ['error', 'in-try-catch'],
// consistent type import
'@typescript-eslint/consistent-type-imports': ['error', {
prefer: 'type-imports',
fixStyle: 'inline-type-imports',
}],
// ห้ามใช้ require() ใน ESM
'@typescript-eslint/no-require-imports': 'error',
}
TypeScript ที่ตรวจโดย ESLint vs TypeScript Compiler
| ตรวจโดย | ตัวอย่าง |
|---|---|
| TypeScript compiler | type mismatch, missing properties |
| ESLint rules | no-floating-promises, prefer-nullish-coalescing |
| Prettier | formatting, indentation, semicolons |
ไม่ต้องให้ ESLint ทำงานซ้ำกับ TypeScript compiler — ใช้ ESLint เพื่อ enforce patterns ที่ TS ไม่ตรวจ