Travis' Guitar Method
← Back to Home

TypeScript Tips for React Developers

Travis Sharp·

TypeScript has become the de facto standard for modern React development. Here are some practical tips to help you write better TypeScript code in your React projects.

1. Use Interface for Props

Always define interfaces for your component props:

interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: 'primary' | 'secondary';
  disabled?: boolean;
}

export const Button: React.FC<ButtonProps> = ({ 
  label, 
  onClick, 
  variant = 'primary',
  disabled = false 
}) => {
  return (
    <button 
      onClick={onClick}
      disabled={disabled}
      className={`btn btn-${variant}`}
    >
      {label}
    </button>
  );
};

2. Leverage Type Inference

Let TypeScript infer types when possible:

// Good - TypeScript infers the type
const [count, setCount] = useState(0);

// Unnecessary - only specify when needed
const [count, setCount] = useState<number>(0);

// Necessary - when initial value is null/undefined
const [user, setUser] = useState<User | null>(null);

3. Use Discriminated Unions

For state management with different states:

type LoadingState = 
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: User }
  | { status: 'error'; error: string };

function UserProfile({ state }: { state: LoadingState }) {
  switch (state.status) {
    case 'idle':
      return <div>Click to load</div>;
    case 'loading':
      return <div>Loading...</div>;
    case 'success':
      return <div>Hello, {state.data.name}!</div>;
    case 'error':
      return <div>Error: {state.error}</div>;
  }
}

4. Type Event Handlers Properly

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  console.log(e.target.value);
};

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault();
  // handle form submission
};

5. Use Generics for Reusable Components

interface ListProps<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
}

function List<T>({ items, renderItem }: ListProps<T>) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{renderItem(item)}</li>
      ))}
    </ul>
  );
}

Conclusion

TypeScript might seem like extra work at first, but it pays dividends in catching bugs early, providing better IDE support, and making refactoring safer. Start with these patterns and gradually incorporate more advanced TypeScript features as you become comfortable.

Happy typing! 🎯