React TypeScript Development
Core Patterns
Component Structure
tsx
import { type FC, type ReactNode } from 'react';
interface ComponentProps {
children?: ReactNode;
variant?: 'primary' | 'secondary';
disabled?: boolean;
onClick?: () => void;
}
export const Component: FC<ComponentProps> = ({
children,
variant = 'primary',
disabled = false,
onClick,
}) => {
return (
<div
className={`component component--${variant}`}
data-disabled={disabled}
onClick={disabled ? undefined : onClick}
>
{children}
</div>
);
};
Typing Guidelines
| Pattern | Use |
|---|---|
FC<Props> | Standard functional components |
ReactNode | Children, any renderable content |
ComponentPropsWithoutRef<'button'> | Extend native HTML element props |
forwardRef<HTMLDivElement, Props> | Components needing ref forwarding |
Event Handler Types
tsx
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void; onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void; onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void; onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
Custom Hooks Pattern
tsx
import { useState, useCallback } from 'react';
interface UseToggleReturn {
value: boolean;
toggle: () => void;
setTrue: () => void;
setFalse: () => void;
}
export const useToggle = (initialValue = false): UseToggleReturn => {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => setValue(v => !v), []);
const setTrue = useCallback(() => setValue(true), []);
const setFalse = useCallback(() => setValue(false), []);
return { value, toggle, setTrue, setFalse };
};
Context Pattern
tsx
import { createContext, useContext, type FC, type ReactNode } from 'react';
interface ThemeContextValue {
theme: 'light' | 'dark';
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextValue | null>(null);
export const useTheme = (): ThemeContextValue => {
const context = useContext(ThemeContext);
if (!context) throw new Error('useTheme must be used within ThemeProvider');
return context;
};
File Naming
code
ComponentName/ ├── ComponentName.tsx # Implementation ├── ComponentName.types.ts # Types (optional) ├── ComponentName.stories.tsx # Storybook ├── index.ts # Exports
Best Practices
- •Explicit return types for public functions
- •Discriminated unions for complex state
- •
as constfor literal types - •Generic components for reusable patterns
- •Handle undefined explicitly
Integration
- •Atomic Design: See atomic-design skill for hierarchy
- •CSS Tokens: See css-tokens skill for styling
- •Storybook: See storybook skill for docs