Skip to content

TypeScript

This content is for Beta. Switch to the latest version for up-to-date documentation.

cva offers the VariantProps helper to extract variant types.

VariantProps contains public variant props, not class or className. It omits variant names prefixed with _; see Internal variants.

components/button.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.

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:

components/button.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" });