Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE]: add TS checklist #13

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions typescript/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,178 @@
# TypeScript Best Practices

1. **Consistent Coding Style**:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the official lint recommended configuration is :
https://github.com/typescript-eslint/typescript-eslint
https://typescript-eslint.io/getting-started
https://typescript-eslint.io/users/configs/

I think we dont need again to use "airbnb-typescript".

- **Explanation**: Use a linter like ESLint to maintain a consistent coding style.
- @typescript-eslint/parser
- @typescript-eslint/eslint-plugin
- eslint-config-airbnb-typescript

Configure ESLint: Create or modify the `.eslintrc.json` file at the root of your project with the following configuration:

```json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend to not add a configuration code since it can oftenly changes. We can say:

{
"extends": [
"airbnb-typescript"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "single"],
"no-unused-vars": "error",
"eqeqeq": ["error", "always"],
"curly": ["error", "all"],
"no-console": "warn",
"consistent-return": "error",
"prefer-const": "error"
}
}
```

This configuration allows you to benefit from Airbnb's best practices while integrating TypeScript specifics.

2. **Type Annotations**:
- **Explanation**: Provide type annotations for function arguments and return values to ensure type safety.
```typescript
function greet(name: string): string {
return `Hello, ${name}`;
}
```

3. **Interfaces**:
- **Explanation**: Prefer interfaces over type aliases for defining object shapes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personally I prefer using type until I need to "extends" then I use interface.
type is more intuitive to define type.
interface is more about contract that an object must adhere to or protocol.

```typescript
interface User {
name: string;
age: number;
}
```

4. **Avoid `any`**:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and unkonw

- **Explanation**: Using `any` defeats the purpose of TypeScript's type safety.
```typescript
let data: any; // Avoid this
let userData: User; // Prefer this
```

5. **Strict Null Checks**:
- **Explanation**: Enable strict null checks to prevent null or undefined errors.
```typescript
let nullableString: string | null = null;
```

6. **Use `readonly` for Immutability**:
- **Explanation**: Use `readonly` for properties that should not be modified after initialization.
```typescript
interface User {
readonly id: number;
name: string;
age: number;
}
```

7. **Prefer `const` over `let`**:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is more related to JS than a specific TS feature, it's common for both JS and TS.
We can have as prerequisite at the begin for example: Adhere to JS best practices => link to JS gems.

- **Explanation**: Use `const` for variables that will not be reassigned.
```typescript
const userName: string = 'Alice';
```

8. **Use Utility Types**:
- **Explanation**: Use TypeScript utility types like `Partial`, `Pick`, `Omit` to manipulate types.
```typescript
interface User {
name: string;
age: number;
email: string;
}

type UserWithoutEmail = Omit<User, 'email'>;
```

9. **Avoid Magic Numbers and Strings**:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- **Explanation**: Define constants for recurring values to make the code more readable and maintainable.
```typescript
const MAX_USERS = 100;

function createUser(name: string): User {
if (users.length >= MAX_USERS) {
throw new Error('Max users reached');
}
// ...
}
```

10. **Document Your Code**:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- **Explanation**: Use JSDoc comments to document functions and interfaces.
```typescript
/**
* Greets a user by name.
* @param name - The name of the user.
* @returns A greeting message.
*/
function greet(name: string): string {
return `Hello, ${name}`;
}
```

11. **Use of Enums**:
- **Explanation**: Use enums to represent a set of named values, improving code readability and maintainability.
```typescript
enum UserRole {
Admin = 'Admin',
User = 'User',
Guest = 'Guest'
}

function getPermissions(role: UserRole) {
switch (role) {
case UserRole.Admin:
return ['read', 'write', 'delete'];
case UserRole.User:
return ['read', 'write'];
case UserRole.Guest:
return ['read'];
}
}
```

12. **Use of Literal Types**:
- **Explanation**: Use literal types for simple sets of values to ensure type safety and flexibility.
```typescript
type OrderStatus = 'Pending' | 'Shipped' | 'Delivered' | 'Cancelled';

function updateOrderStatus(orderId: number, status: OrderStatus) {
// Logic to update order status
console.log(`Order ${orderId} is now ${status}`);
}
```

13. **Use of `const` with `as const`**:
- **Explanation**: Use `const` with `as const` to define immutable objects, ensuring that values are not accidentally modified.
```typescript
const Config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retryAttempts: 3
} as const;

type ConfigType = typeof Config;

function initializeApp(config: ConfigType) {
console.log(`Initializing app with API URL: ${config.apiUrl}`);
// App initialization logic
}
```


## Ressources

- [TypeScript GitBook : Un ouvrage open-source sur TypeScript](https://basarat.gitbook.io/typescript/)
- [Typescriptlang Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
- [The Concise TypeScript Book](https://typescript-book.vercel.app/books/the-concise-typescript-book/)
- [TS Playground](https://www.typescriptlang.org/play)
- [TS config cheat sheet](https://www.totaltypescript.com/tsconfig-cheat-sheet)