Skip to content

Instantly share code, notes, and snippets.

@pjchender
Last active June 24, 2021 16:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjchender/0bf0ca9d5f90c00bc9b5cf6741063a60 to your computer and use it in GitHub Desktop.
Save pjchender/0bf0ca9d5f90c00bc9b5cf6741063a60 to your computer and use it in GitHub Desktop.
Limiting Props
// frontendmasters.com/courses/react-typescript/limiting-props/
/* eslint-disable no-restricted-syntax */
/* eslint-disable react/require-default-props */
type ButtonBase = {
children: string;
};
type PrimaryButtonProps = ButtonBase & {
primary: boolean;
secondary?: never;
destructive?: never;
};
type SecondaryButtonProps = ButtonBase & {
primary?: never;
secondary: boolean;
destructive?: never;
};
type DestructiveButtonProps = ButtonBase & {
primary?: never;
secondary?: never;
destructive: boolean;
};
type ButtonProps =
| PrimaryButtonProps
| SecondaryButtonProps
| DestructiveButtonProps;
const createClassNames = (classes: { [key: string]: boolean }): string => {
let classNames = '';
for (const [key, value] of Object.entries(classes)) {
if (value) classNames += `${key} `;
}
return classNames.trim();
};
const Button = ({
children,
primary = false,
secondary = false,
destructive = false,
}: ButtonProps) => {
const classNames = createClassNames({ primary, secondary, destructive });
return (
<button type="button" className={classNames}>
{children}
</button>
);
};
const Application = () => {
return (
<main>
<Button primary>Primary</Button>
<Button secondary>Secondary</Button>
<Button destructive>Destructive</Button>
</main>
);
};
export default Application;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment