TSX1type Props = { 2 type: "link" | "button"; 3 href?: string; 4 onClick?: () => void; 5}; 6 7const SmartButton = ({ type, href, onClick }: Props) => { 8 if (type === "link") { 9 return <a href={href}>Link</a>; 10 } 11 return <button onClick={onClick}>Button</button>; 12};
β Problem: This allows invalid cases. What if someone passes type: "link" but doesn't provide an href?
β Solution: Discriminated Union to the Rescue!
TSX1type LinkButton = { 2 type: "link"; 3 href: string; 4}; 5 6type RegularButton = { 7 type: "button"; 8 onClick: () => void; 9}; 10 11type SmartButtonProps = LinkButton | RegularButton; 12 13const SmartButton = (props: SmartButtonProps) => { 14 if (props.type === "link") { 15 return <a href={props.href}>Link</a>; 16 } 17 return <button onClick={props.onClick}>Button</button>; 18};
π Now itβs type-safe:
Updated