Advanced TypeScript Patterns for Real-Time Collaboration Tools

Explore design patterns and techniques in TypeScript to build efficient real-time collaborative applications.

0 likes
10 views

Rule Content

---
description: Enforce advanced TypeScript patterns for building efficient real-time collaborative applications
globs: src/**/*.ts, src/**/*.tsx
tags: [typescript, real-time, collaboration, design-patterns]
priority: 1
version: 1.0.0
---

# Advanced TypeScript Patterns for Real-Time Collaboration Tools

## Context
- Applicable to TypeScript projects focused on developing real-time collaborative applications.
- Aims to enhance code quality, maintainability, and scalability through advanced TypeScript design patterns.

## Requirements

- **Strict Type Safety**: Enable strict compiler options in `tsconfig.json` to enforce type safety.

  ```json
  {
    "compilerOptions": {
      "strict": true,
      "noImplicitAny": true,
      "strictNullChecks": true,
      "strictFunctionTypes": true,
      "strictBindCallApply": true,
      "strictPropertyInitialization": true,
      "noImplicitThis": true,
      "alwaysStrict": true,
      "noUncheckedIndexedAccess": true,
      "exactOptionalPropertyTypes": true
    }
  }
  ```

- **Use of Interfaces**: Prefer interfaces over type aliases for defining object shapes to leverage declaration merging and better readability.

  ```typescript
  // Good
  interface User {
    id: string;
    name: string;
    email: string;
  }

  // Bad
  type User = {
    id: string;
    name: string;
    email: string;
  };
  ```

- **Avoid 'any' Type**: Refrain from using the `any` type; use `unknown` when the type is not known and perform type narrowing.

  ```typescript
  // Good
  let data: unknown;
  if (typeof data === 'string') {
    // data is treated as a string here
  }

  // Bad
  let data: any;
  ```

- **Utilize Utility Types**: Employ TypeScript utility types like `Partial<T>`, `Required<T>`, `Readonly<T>`, `Pick<T, K>`, and `Omit<T, K>` to create flexible and reusable type definitions.

  ```typescript
  interface User {
    id: string;
    name: string;
    email: string;
  }

  // Good
  type PartialUser = Partial<User>;
  type ReadonlyUser = Readonly<User>;
  ```

- **Implement Discriminated Unions**: Use discriminated unions for complex type relationships to enhance type safety and readability.

  ```typescript
  // Good
  interface TextMessage {
    type: 'text';
    content: string;
  }

  interface ImageMessage {
    type: 'image';
    url: string;
  }

  type Message = TextMessage | ImageMessage;

  function handleMessage(message: Message) {
    switch (message.type) {
      case 'text':
        // handle text message
        break;
      case 'image':
        // handle image message
        break;
    }
  }
  ```

- **Use Generics for Reusability**: Apply generics to create reusable and type-safe components and functions.

  ```typescript
  // Good
  function identity<T>(arg: T): T {
    return arg;
  }

  const result = identity<string>('Hello');
  ```

- **Avoid Type Assertions**: Minimize the use of type assertions (`as`) to prevent bypassing the type system; instead, use type guards and proper type definitions.

  ```typescript
  // Good
  function isString(value: unknown): value is string {
    return typeof value === 'string';
  }

  let data: unknown;
  if (isString(data)) {
    // data is treated as a string here
  }

  // Bad
  let data: unknown;
  let str = data as string;
  ```

- **Enable Strict Compiler Options**: Ensure all strict TypeScript compiler options are enabled to catch potential errors during development.

  ```json
  {
    "compilerOptions": {
      "strict": true,
      "noImplicitAny": true,
      "strictNullChecks": true,
      "strictFunctionTypes": true,
      "strictBindCallApply": true,
      "strictPropertyInitialization": true,
      "noImplicitThis": true,
      "alwaysStrict": true,
      "noUncheckedIndexedAccess": true,
      "exactOptionalPropertyTypes": true
    }
  }
  ```

## Examples

<example>
// Good: Using interfaces and utility types
interface User {
  id: string;
  name: string;
  email: string;
}

type PartialUser = Partial<User>;
type ReadonlyUser = Readonly<User>;
</example>

<example type="invalid">
// Bad: Using type alias and 'any' type
type User = {
  id: string;
  name: string;
  email: string;
};

let data: any;
</example>