Typescript
Tailwind Variants 开箱即用地提供了类型支持,但本页面包含了一些进一步的实用工具和技巧。
从组件中提取变体
您可以使用 VariantProps 工具来从组件中提取变体。
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'
}
]
});
/**
* 结果:
* 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>;
};
必填变体
Tailwind Variants 尚不提供将变体设为必填的方法,但您可以使用 TypeScript 的 工具类型(Utility Types) 来实现。
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: [...],
});
/**
* 结果:
* 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 错误:
// 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 });
此示例摘自 CVA 项目在 Github 上的 “必填变体” 部分,该项目由 Joe Bell 开发。