Sets of props in React and Typescript

nikitarudenko

Nikita Rudenko

Posted on June 15, 2021

Sets of props in React and Typescript

Sometimes when writing an app in React you might have a component that changes its look and logic dramatically depending on provided props. In addition, if a particular prop provided, the other props become either required or restricted. That hidden prop relation can be explained in documentation but if your project uses Typescript there is a great opportunity to utilize what I call "sets of props".

Simple example

It's usually not the best idea to make buttons look like links and vice versa but let's ignore this for the sake of clarity. The code snippet below is so-called Clickable component which can be either a link or a button that shares the same style but has different behavior depending on props.

import { ReactNode } from 'react'

interface BaseProps {
  children: ReactNode
}

interface AsButtonProps extends BaseProps {
  as: 'button'
  onClick: () => void
  href?: never
}

interface AsLinkProps extends BaseProps {
  as: 'a'
  href: string
  onClick?: never
}

type ClickableProps = AsButtonProps | AsLinkProps

const Clickable = ({ children, as, onClick, href }: ClickableProps) => {
  return (
    <>
      {as === 'a' && (
        <a href={href}>{children}</a>
      )}

      {as === 'button' && (
        <button onClick={onClick}>{children}</button>
      )}
    </>
  )
}

export default Clickable
Enter fullscreen mode Exit fullscreen mode

The component has four props. children is required in any case so it's put under the BaseProps interface. Both AsButtonProps and AsLinkProps extended from BaseProps and represent two sets of props. The active set depends on the value of the as prop while the type never for unused props makes sure that Typescript will yell if someone is using a prop which does nothing.

Here is a scheme:
sets-of-props-clickable-scheme

Summary

This pattern is obviously not limited to props in React. It's widely used in the types of various npm packages. Now you can add it to your arsenal and build reusable components/utils with better API for you and your team.

Links

๐Ÿ’– ๐Ÿ’ช ๐Ÿ™… ๐Ÿšฉ
nikitarudenko
Nikita Rudenko

Posted on June 15, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

ยฉ TheLazy.dev

About