DEV Community

Discussion on: Understanding TypeScript

Collapse
lukeshiru profile image
LUKESHIRU

Possible typo: You're not using variation, and the returned valued shouldn't have {} surrounding the JSX. Plus the variation property doesn't exists in native buttons, so you might want to use className instead? I believe the code should actually be like this:

export type ButtonProps = {
    /**
     * a text for the button
     */
    buttonText: string;
    /**
     * the variation of the button
     */
    variation?: "primary" | "secondary";
};

export const Button = ({
    buttonText = "add to cart",
    variation
}: ButtonProps) => <button className={`btn-${variation}`}>{buttonText}</button>;

// Usage
<Button buttonText="Hello!" variation="primary" />;
Enter fullscreen mode Exit fullscreen mode

There are a few improvements that can be made to that Button component both from the React perspective, and from TypeScript. Instead of just using a button, you can "extend" it by making use of a React type called IntrinsicElements, and in top of that, the button text is just its children, so you can reuse that prop instead of having a custom prop for it. So the code could look something like this:

import type { FC } from "react";

export type ButtonProps = JSX.IntrinsicElements["button"] & {
    /**
     * the variation of the button
     */
    readonly variation?: "primary" | "secondary";
};

export const Button: FC<ButtonProps> = ({
    children = "add to cart",
    className = "",
    variation,
    ...props
}: ButtonProps) => (
    <button className={`btn-${variation} ${className}`} {...props}>
        {children}
    </button>
);

// Usage
<Button variation="primary">Hello!</Button>
Enter fullscreen mode Exit fullscreen mode

Hope it's helpful ^_^
Cheers!

Collapse
debs_obrien profile image
Debbie O'Brien Author

hey, thanks for the reply and detailed answer. looks good. I still havent dived into intrinsicElements yet so will take a look at them. And you're right. I need to use children more. My next post will be on children. As for variation yeah looks good with the btn- which makes it clear why it's there. My quick example is probably not that useful and I do have it in production with a function that creates the classname depending on the prop passed in but that was taking it one step further. so much to learn...... :) thanks again