Skip to content
Docs
Typescript

Typescript

Tailwind Variants provides typing out of the box, but this page contains some further utilities and tips.

Extract variants from a component

You can use the VariantProps utility to extract variants from a component.

import { tv, type VariantProps } from 'tailwind-variants';
 
export const button = tv({
  base: 'px-4 py-1.5 rounded-full hover:opacity-80',
  variants: {
    color: {
      primary: 'bg-blue-500 text-white',
      neutral: 'bg-zinc-500 text-black dark:text-white'
    },
    flat: {
      true: 'bg-transparent'
    }
  },
  defaultVariants: {
    color: 'primary'
  },
  compoundVariants: [
    {
      color: 'primary',
      flat: true,
      class: 'bg-blue-500/40'
    },
    {
      color: 'neutral',
      flat: true,
      class: 'bg-zinc-500/20'
    }
  ]
});
 
/**
 * Result:
 * color?: "primary" | "neutral"
 * flat?: boolean
 */
 
type ButtonVariants = VariantProps<typeof button>;
 
interface ButtonProps extends ButtonVariants {
  children: React.ReactNode;
}
 
export const Button = (props: ButtonProps) => {
  return <button className={button(props)}>{props.children}</button>;
};

Required variants

Tailwind Variants doesn't offer a way to make variants required yet, but you can use TypeScript's Utility Types (opens in a new tab) to achieve this.

import { tv, type VariantProps } from 'tailwind-variants'
 
const buttonStyles = tv({
  base: "px-4 py-1.5 rounded-full hover:opacity-80",
  variants: {
    color: {
      primary: "bg-blue-500 text-white",
      neutral: "bg-zinc-500 text-black dark:text-white",
    },
    requiredFlat: {
      true: "bg-transparent",
      false: "bg-white",
    },
  },
  defaultVariants: {
    color: "primary",
  },
  compoundVariants: [...],
});
 
/**
 * Result:
 * color?: "primary" | "neutral"
 * flat?: boolean
 */
type ButtonVariants = VariantProps<typeof buttonStyles>
 
export interface ButtonProps
  extends Omit<ButtonVariants, "requiredFlat">,
    Required<Pick<ButtonVariants, "requiredFlat">> {}
 
export const button = (props: ButtonProps) => buttonStyles(props);
 
// ❌ TypeScript Error:
// Argument of type "{}": is not assignable to parameter of type "ButtonProps".
// Property "requiredFlat" is missing in type "{}" but required in type "ButtonProps".
button({});
 
// ✅
button({ requiredFlat: true });

This sample is taken from the "Required Variants" section of the CVA (opens in a new tab) project on Github, which was developed by Joe Bell (opens in a new tab).