mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Enhanced code review guidelines and clarified code style documentation. - 📚 **Docs**: Added emphasis on adherence to review guidelines - 📚 **Docs**: Clarified documentation requirements in code style - 🛠️ **Refactor**: Updated import paths in input controls styles - 📚 **Docs**: Expanded tech stack documentation with new libraries
5.8 KiB
5.8 KiB
Code Style Guidelines
General Principles
- Readability First: Write code that is easy to read and understand.
- Consistency: Follow the same patterns and conventions throughout the codebase.
- Clean Code: Avoid unnecessary complexity and keep functions small and focused.
Extended Guidelines for Angular and TypeScript
This section extends the core code style principles with Angular-specific and advanced TypeScript best practices to ensure consistency and maintainability in our projects.
Angular Enhancements
- Change Detection: Use the OnPush strategy by default for better performance.
- Lifecycle Hooks: Explicitly implement Angular lifecycle interfaces.
- Template Management: Keep templates concise and use the async pipe to handle observables.
- Component Structure: Follow best practices for component modularization to enhance readability and testability.
TypeScript Enhancements
- Strict Type Checking: Enable strict mode (
strict: true) and avoid excessive use ofany. - Interfaces vs. Types: Prefer interfaces for object definitions and use type aliases for unions and intersections.
- Generics: Use meaningful type parameter names and constrain generics when applicable.
- Documentation: Employ JSDoc comments functions and generic parameters to improve code clarity.
TypeScript Guidelines
-
Strict Typing:
- Enable
strict: truein tsconfig.json - Avoid
anyunless absolutely necessary - Use
unknowninstead ofanywhen type is truly unknown - Always specify return types for functions
- Use type inference for variable declarations where types are obvious
// Good const user: User = getUserById('123'); const items = ['apple', 'banana']; // Type inference is fine here // Bad const user: any = getUserById('123'); const items: string[] = ['apple', 'banana']; // Unnecessary type annotation - Enable
-
Interfaces and Types:
- Prefer
interfaceovertypefor object definitions - Use
typefor unions, intersections, and mapped types - Follow Angular's naming convention:
IComponentPropsfor props interfaces - Extend interfaces instead of repeating properties
- Use readonly modifiers where appropriate
// Good interface IBaseProps { readonly id: string; name: string; } interface IUserProps extends IBaseProps { email: string; } type ValidationResult = 'success' | 'error' | 'pending'; // Bad type UserProps = { id: string; name: string; email: string; }; - Prefer
-
Enums and Constants:
- Use
const enumfor better performance - Only use regular
enumwhen runtime access is required - Prefer union types for simple string literals
- Use
-
Functions and Methods:
- Use arrow functions for callbacks and class methods
- Explicitly type parameters and return values
- Keep functions pure when possible
- Use function overloads for complex type scenarios
- Document complex functions with JSDoc
// Good /** * Fetches a user by ID and transforms it to the required format * @param id - The user's unique identifier * @param includeDetails - Whether to include additional user details */ const getUser = (id: string, includeDetails = false): Promise<IUser> => { // ...implementation }; // Bad function getUser(id) { // ...implementation } -
Generics:
- Use meaningful type parameter names (e.g.,
Tfor type,Kfor key) - Constrain generic types when possible using
extends - Document generic parameters using JSDoc
- Use meaningful type parameter names (e.g.,
Example:
// Good
interface IUserProps {
id: string;
name: string;
}
interface IAdminProps extends IUserProps {
permissions: string[];
}
const enum UserRole {
Admin = 'ADMIN',
User = 'USER',
}
const getUser = <T extends IUserProps>(id: string): Promise<T> => {
// ...implementation
};
// Bad
type User = {
id: any;
name: any;
};
function getUser(id) {
// ...implementation
}
Angular-Specific Guidelines
-
Components:
- Use OnPush change detection strategy by default
- Implement lifecycle hooks interfaces explicitly
- Keep templates small and focused
- Use async pipe instead of manual subscription management
// Good @Component({ selector: 'app-user-list', changeDetection: ChangeDetectionStrategy.OnPush, }) export class UserListComponent implements OnInit, OnDestroy { users$ = this.userService.getUsers().pipe(shareReplay(1)); } // Bad @Component({ selector: 'app-user-list', }) export class UserListComponent { users: User[] = []; subscription: Subscription; ngOnInit() { this.subscription = this.userService.getUsers().subscribe((users) => (this.users = users)); } }
Project-Specific Preferences
- Frameworks: Follow best practices for Nx, Hono, and Zod.
- Testing: Use Jest with Spectator for unit tests and follow the Arrange-Act-Assert pattern.
- File Naming: Use kebab-case for filenames (e.g.,
my-component.ts). - Comments: Use JSDoc for documenting functions, classes, and modules.
Formatting
- Indentation: Use 2 spaces for indentation.
- Line Length: Limit lines to 80 characters where possible.
- Semicolons: Always use semicolons.
- Quotes: Use single quotes for strings, except when using template literals.
Linting and Tools
- Use ESLint with the recommended TypeScript and Nx configurations.
- Prettier should be used for consistent formatting.
Example
// Good Example
interface User {
id: string;
name: string;
}
const getUser = (id: string): User => {
// ...function logic...
};
// Bad Example
function getUser(id) {
// ...function logic...
}