51

I'm trying to my component library to use TypeScript and am attempting to convert a stateless functional component in React from ES6/JavaScript to TypeScript. I am wondering how I can avoid duplicating myself while still being able to deconstruct props outside the function while passing it parameters.

My component currently looks like this:

const allowedColors = {
  warning: "fa fa-exclamation",
  info: "fa fa-info",
  success: "fa fa-check",
  danger: "fa fa-minus-circle"
};

const AlertIcon = ({ className, color, ...props }) => (
  <FontAwesomeIcon
    {...props}
    iconClassName={allowedColors[color]}
    className={classNames(`alert-icon-${color}`, className)}
    aria-hidden="true"
    data-ut="alert-icon"
  />
);

AlertIcon.propTypes = {
  className: PropTypes.string,
  color: PropTypes.oneOf(Object.keys(allowedColors)).isRequired
};

How would I go about refactoring this into TypeScript?

1 Answer 1

99
type Color = "warning" | 'info'| 'success' | 'danger'

interface IProps {
  color: Color
}

const AlertIcon = ({ className, color, ...props }: IProps) => { ... }

now when you use AlertIcon the color prop must be of type Color

to account for passing HTML attributes, like className you can do this:

interface IProps extends HTMLAttributes<HTMLElement> { ... }

where HTMLElement is your type of element.

Sign up to request clarification or add additional context in comments.

7 Comments

Need to add [x: string]: any to your IProps
there's a better way to achieve that. see my edit. in anyway, your suggestion enables passing undeclared props which is not very type-safe.
yes, once you get the color name, mapping is up to you. what you did before will work.
Also, nicely explained here: medium.com/@rileyhilliard/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.