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