TypeScript Prop Definition
Interface Convention
Use `interface` for component props:
```tsx
/**
- Props for the Button component
/
interface ButtonProps {
/* Button text or content /
children: React.ReactNode;
/* Click handler /
onClick?: () => void;
/* Whether button is disabled */
disabled?: boolean;
}
export function Button({ children, onClick, disabled }: ButtonProps) {
// ...
}
```
JSDoc Comments
Document each prop:
```tsx
interface UserCardProps {
/** User's full name /
name: string;
/* User's email address /
email: string;
/* Optional avatar URL */
avatarUrl?: string;
}
```
Generics for Reusable Components
```tsx
interface ListProps {
items: T[];
renderItem: (item: T) => React.ReactNode;
keyExtractor: (item: T) => string;
}
function List({ items, renderItem, keyExtractor }: ListProps) {
return (
{items.map(item => (
-
{renderItem(item)}
))}
);
}
```
Utility Types
Extending Native Props
```tsx
interface ButtonProps extends React.ButtonHTMLAttributes {
variant?: 'default' | 'destructive';
}
```
Pick/Omit
```tsx
type UserPublicInfo = Pick<User, 'name' | 'email'>;
type UserWithoutPassword = Omit<User, 'password'>;
```
Partial
```tsx
type PartialUser = Partial; // All fields optional
```
cva + VariantProps Pattern
```tsx
import { cva, type VariantProps } from 'class-variance-authority';
const buttonVariants = cva("base-classes", {
variants: {
variant: {
default: "...",
destructive: "...",
},
size: {
default: "...",
sm: "...",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
});
// Automatically inferred type from cva
interface ButtonProps
extends React.ButtonHTMLAttributes,
VariantProps {
// variant?: "default" | "destructive"
// size?: "default" | "sm"
}
```
Anti-Patterns
ā Using `any` type
ā Missing JSDoc comments
ā Manually typing variants (use VariantProps)
ā `children: any` (use `React.ReactNode`)
ā
Explicit interface with JSDoc
ā
Use VariantProps for cva
ā
Leverage utility types
Token Estimate: ~2,800 tokens