Background
When working in a team of developers, it's essential to follow a consistent coding style. Clean Code principles help in maintaining a codebase that's readable, maintainable, and avoids the dreaded 💩 smells. Adopting Clean Code Principles not only improves the quality of your code but also reflects the professionalism of the development team.
In projects using React and TypeScript, establishing code conventions is crucial as both technologies allow for various ways to write code. This post will guide you through setting up clean code principles and code conventions for TypeScript + React.
Clean Code Principles for TypeScript + React
Here are some key principles to follow:
1. Meaningful Naming
- Use clear and descriptive names for variables, functions, components, etc.
// ❌ Bad
const d = (x) => x.map((a) => a.value);
// ✅ Good
const getValues = (items: Item[]) => items.map((item) => item.value);
2. Single Responsibility Principle (SRP)
- Each component should have only one responsibility.
// ❌ Bad: Mixing UI rendering with API logic
// ✅ Good: Separate UI and logic into custom hooks or service layers
3. Avoid Magic Numbers & Strings
// ❌
if (status === 2) {}
// ✅
const STATUS_APPROVED = 2;
if (status === STATUS_APPROVED) {}
4. Keep Components Small and Focused
- Avoid creating components larger than 200 lines. Break them into smaller subcomponents when needed.
5. Use TypeScript Effectively
- Always define explicit types for props, state, and function return types.
Code Convention: ESLint + Prettier Setup
- Install Dependencies
npm install -D eslint prettier eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-prettier
-
.eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['react', '@typescript-eslint', 'prettier'],
extends: [
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended'
],
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
ecmaFeatures: { jsx: true }
},
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/explicit-function-return-type': 'warn',
'react/react-in-jsx-scope': 'off', // for Next.js / React 17+
},
settings: {
react: { version: 'detect' }
}
};
-
prettier.config.js
module.exports = {
semi: true,
singleQuote: true,
printWidth: 100,
trailingComma: 'es5',
};
- Add Scripts to
package.json
"scripts": {
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"format": "prettier --write ."
}
Add Pre-commit Hooks with Husky + Lint-Staged
- Install Husky and Lint-Staged
npm install -D husky lint-staged
npx husky install
- Configure lint-staged in
package.json
"lint-staged": {
"src/**/*.{ts,tsx}": [
"npm run lint:fix",
"npm run format"
]
}
- Add Pre-commit Hook
npx husky add .husky/pre-commit "npx lint-staged"
Extra Resouces
Clean Code (Book) by Robert C. Martin
Refactoring UI by Adam Wathan & Steve Schoger
Top comments (0)