---
title: "TypeScript"
description: "Extract variant types with VariantProps and require specific variants with TypeScript utility types."
url: "https://cva.style/beta/getting-started/typescript/"
---

## Extracting variant types

`cva` offers the `VariantProps` helper to extract variant types.

Keep component props inferred

Use `VariantProps` instead of repeating variant unions. Combine it with native element props when wrapping a UI component, and forward semantic attributes such as `disabled` to the element as well as the class function.

`VariantProps` contains public variant props, not `class` or `className`. It omits variant names prefixed with `_`; see [Internal variants](https://cva.style/beta/getting-started/variants#internal-variants).

components/button.ts

```ts
import { cva, type VariantProps } from "cva";


export const button = cva({
  base: "button",
  variants: {
    intent: { primary: "button--primary", secondary: "button--secondary" },
  },
});


export type ButtonProps = VariantProps<typeof button>;
```

For a React component that combines these variants with native button props, see [generating a React variant gallery](https://cva.style/beta/getting-started/tools#generate-a-react-variant-gallery).

## Required variants

To keep the API small and unopinionated, `cva` **doesn’t** offer a built-in solution for setting required variants.

Instead, we recommend using TypeScript’s [Utility Types](https://www.typescriptlang.org/docs/handbook/utility-types.html):

components/button.ts

```ts
import { cva, type VariantProps } from "cva";


export type ButtonVariantProps = VariantProps<typeof buttonVariants>;
export const buttonVariants = cva({
  base: "…",
  variants: {
    optional: { a: "…", b: "…" },
    required: { a: "…", b: "…" },
  },
});


/**
 * Button
 */
export interface ButtonProps
  extends
    Omit<ButtonVariantProps, "required">,
    Required<Pick<ButtonVariantProps, "required">> {}


export const button = (props: ButtonProps) => buttonVariants(props);


// ❌ TypeScript Error:
// Argument of type "{}": is not assignable to parameter of type "ButtonProps".
//   Property "required" is missing in type "{}" but required in type
//   "ButtonProps".
button({});


// ✅
button({ required: "a" });
```
