Bilal Gokdag
Back to Blog

Clean Code Practices with React and TypeScript

Building low-error, maintainable React component architecture using advanced TypeScript features — Generics, Utility Types, and Discriminated Unions.

Clean Code Practices with React and TypeScript

Treating TypeScript purely as a tool for avoiding the any type wastes most of its potential. As a senior frontend engineer, you should use TypeScript as a strict contract that enforces business logic at the code level.

1. Constraining Possible States with Discriminated Unions

In complex interfaces, it's critical not to let a component's possible states get tangled up with each other.

// ❌ Bad: allows mutually contradictory props
interface ButtonProps {
  isLoading?: boolean;
  text?: string;
  icon?: React.ReactNode;
}

// ✅ Good (Discriminated Unions): a type-safe design
type ButtonState =
  | { state: "loading" }
  | { state: "success"; text: string }
  | { state: "error"; errorMsg: string };

type SecureButtonProps = ButtonState & { onClick: () => void };

export function ActionButton(props: SecureButtonProps) {
  if (props.state === "loading") return <Spinner />;
  if (props.state === "error")
    return <span className="text-red-500">{props.errorMsg}</span>;
  return <button onClick={props.onClick}>{props.text}</button>;
}

Need this kind of work done on your project?

I build production-ready, high-performance web applications — let's talk about what you're building.

Start a Project