TypeScript Tips and Tricks for Better Code

TypeScript has become an essential tool for modern web development. Here are some practical tips to make your TypeScript code more robust and maintainable.

1. Use Strict Mode

Always enable strict mode in your tsconfig.json:

{
  "compilerOptions": {
    "strict": true
  }
}

This catches many common errors and enforces better coding practices.

2. Leverage Type Inference

TypeScript is smart enough to infer types in many cases. Don’t over-annotate:

// Good - let TypeScript infer the type
const numbers = [1, 2, 3, 4, 5];

// Unnecessary - TypeScript already knows this is number[]
const numbers: number[] = [1, 2, 3, 4, 5];

3. Use Union Types for Flexibility

Union types allow you to handle multiple possible values:

type Status = 'loading' | 'success' | 'error';

function handleStatus(status: Status) {
  switch (status) {
    case 'loading':
      return 'Please wait...';
    case 'success':
      return 'Operation completed!';
    case 'error':
      return 'Something went wrong.';
  }
}

4. Utility Types Are Your Friends

TypeScript provides many utility types that can save you time:

// Pick only certain properties
type UserSummary = Pick<User, 'id' | 'name' | 'email'>;

// Make all properties optional
type PartialUser = Partial<User>;

// Make all properties required
type RequiredUser = Required<User>;

5. Use Interfaces for Object Shapes

Interfaces are great for defining object shapes and can be extended:

interface BaseUser {
  id: string;
  name: string;
}

interface AdminUser extends BaseUser {
  permissions: string[];
}

6. Handle Null and Undefined

Use optional chaining and nullish coalescing:

// Safe property access
const userName = user?.profile?.name ?? 'Anonymous';

// Type guards for runtime checks
function isUser(obj: any): obj is User {
  return obj && typeof obj.id === 'string';
}

These tips will help you write more reliable and maintainable TypeScript code. Remember, the goal is to catch errors at compile time rather than runtime.