Skip to content

A comprehensive collection of TypeScript patterns, best practices, and advanced React concepts implemented with Next.js 14. This repository demonstrates type-safe development, modern React patterns, and production-ready architectures.

Notifications You must be signed in to change notification settings

jefercort/react-ts-practice

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ React TypeScript Practice with Next.js

A comprehensive collection of TypeScript patterns, best practices, and advanced React concepts implemented with Next.js 14. This repository demonstrates type-safe development, modern React patterns, and production-ready architectures.

πŸ“‹ Table of Contents

🎯 Overview

This repository showcases advanced TypeScript usage with React and Next.js, demonstrating real-world patterns, type safety, and modern development practices. It serves as both a learning resource and a reference implementation for building scalable, type-safe applications.

Goals

  • Master TypeScript with React and Next.js
  • Implement type-safe patterns and best practices
  • Build performant, scalable applications
  • Demonstrate advanced React patterns
  • Showcase modern development workflows

πŸ› οΈ Tech Stack

Core Technologies

  • Next.js 14 - Full-stack React framework with App Router
  • React 18 - UI library with Server Components
  • TypeScript 5 - Type-safe JavaScript
  • Tailwind CSS - Utility-first CSS framework

Key Libraries

  • React Hook Form - Type-safe forms with validation
  • Zod - Schema validation
  • TanStack Query - Data fetching and caching
  • Zustand - Lightweight state management
  • Framer Motion - Animation library
  • React Testing Library - Component testing
  • Jest - Test runner

Development Tools

  • ESLint - Code quality
  • Prettier - Code formatting
  • Husky - Git hooks
  • Commitlint - Commit message linting
  • GitHub Actions - CI/CD

✨ Features

TypeScript Excellence

  • 🎯 Strict Type Checking - No any types, full type safety
  • πŸ”§ Advanced Types - Generics, utility types, conditional types
  • πŸ“ Type Inference - Leveraging TypeScript's powerful inference
  • πŸ—οΈ Type-Safe APIs - End-to-end type safety with tRPC/REST
  • 🎨 Component Patterns - Strongly typed components and hooks

Next.js 14 Features

  • πŸ“ App Router - File-based routing with layouts
  • πŸš€ Server Components - Optimized server-side rendering
  • πŸ’Ύ Server Actions - Type-safe server mutations
  • πŸ”„ Streaming SSR - Progressive rendering
  • πŸ–ΌοΈ Image Optimization - Next/Image with lazy loading
  • 🎯 API Routes - Type-safe backend endpoints

Development Patterns

  • πŸ›οΈ Clean Architecture - Separation of concerns
  • 🧩 Component Composition - Reusable, composable components
  • 🎣 Custom Hooks - Encapsulated, reusable logic
  • πŸ”’ Error Boundaries - Graceful error handling
  • β™Ώ Accessibility - WCAG compliant components

πŸ“ Project Structure

react-ts-practice/
β”œβ”€β”€ app/                      # Next.js App Router
β”‚   β”œβ”€β”€ (auth)/              # Route group for auth
β”‚   β”‚   β”œβ”€β”€ login/
β”‚   β”‚   └── register/
β”‚   β”œβ”€β”€ (dashboard)/         # Protected routes
β”‚   β”‚   β”œβ”€β”€ layout.tsx
β”‚   β”‚   └── dashboard/
β”‚   β”œβ”€β”€ api/                 # API routes
β”‚   β”‚   └── [...]/route.ts
β”‚   β”œβ”€β”€ layout.tsx           # Root layout
β”‚   └── page.tsx             # Home page
β”œβ”€β”€ components/              # React components
β”‚   β”œβ”€β”€ ui/                  # UI components
β”‚   β”‚   β”œβ”€β”€ Button/
β”‚   β”‚   β”‚   β”œβ”€β”€ Button.tsx
β”‚   β”‚   β”‚   β”œβ”€β”€ Button.test.tsx
β”‚   β”‚   β”‚   └── index.ts
β”‚   β”‚   └── Form/
β”‚   β”œβ”€β”€ features/            # Feature components
β”‚   β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   └── dashboard/
β”‚   └── layouts/             # Layout components
β”œβ”€β”€ lib/                     # Library code
β”‚   β”œβ”€β”€ api/                 # API clients
β”‚   β”œβ”€β”€ auth/                # Authentication
β”‚   β”œβ”€β”€ db/                  # Database utilities
β”‚   └── utils/               # Utility functions
β”œβ”€β”€ hooks/                   # Custom React hooks
β”‚   β”œβ”€β”€ useAuth.ts
β”‚   β”œβ”€β”€ useDebounce.ts
β”‚   └── useLocalStorage.ts
β”œβ”€β”€ types/                   # TypeScript types
β”‚   β”œβ”€β”€ api.ts
β”‚   β”œβ”€β”€ models.ts
β”‚   └── global.d.ts
β”œβ”€β”€ services/                # Business logic
β”‚   β”œβ”€β”€ user.service.ts
β”‚   └── product.service.ts
β”œβ”€β”€ store/                   # State management
β”‚   β”œβ”€β”€ auth.store.ts
β”‚   └── cart.store.ts
β”œβ”€β”€ styles/                  # Global styles
β”‚   └── globals.css
β”œβ”€β”€ tests/                   # Test utilities
β”‚   β”œβ”€β”€ setup.ts
β”‚   └── utils.tsx
β”œβ”€β”€ public/                  # Static assets
β”œβ”€β”€ .env.example            # Environment variables
β”œβ”€β”€ next.config.js          # Next.js config
β”œβ”€β”€ tsconfig.json           # TypeScript config
β”œβ”€β”€ tailwind.config.ts      # Tailwind config
└── package.json

🎨 TypeScript Patterns

1. Component Patterns

// Strongly typed functional component
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  isLoading?: boolean;
  children: React.ReactNode;
  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
}

export const Button: React.FC<ButtonProps> = ({
  variant = 'primary',
  size = 'md',
  isLoading = false,
  children,
  onClick,
}) => {
  return (
    <button
      className={cn(
        'rounded-lg font-medium transition-all',
        variants[variant],
        sizes[size],
        isLoading && 'opacity-50 cursor-not-allowed'
      )}
      onClick={onClick}
      disabled={isLoading}
    >
      {isLoading ? <Spinner /> : children}
    </button>
  );
};

2. Custom Hook with TypeScript

// Type-safe custom hook
function useLocalStorage<T>(
  key: string,
  initialValue: T
): [T, (value: T | ((val: T) => T)) => void] {
  const [storedValue, setStoredValue] = useState<T>(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(`Error loading ${key} from localStorage:`, error);
      return initialValue;
    }
  });

  const setValue = (value: T | ((val: T) => T)) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.error(`Error saving ${key} to localStorage:`, error);
    }
  };

  return [storedValue, setValue];
}

3. API Types with Zod

// Schema validation with inference
import { z } from 'zod';

export const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(2).max(50),
  role: z.enum(['user', 'admin', 'moderator']),
  createdAt: z.date(),
  preferences: z.object({
    theme: z.enum(['light', 'dark', 'system']),
    notifications: z.boolean(),
  }).optional(),
});

export type User = z.infer<typeof UserSchema>;

// Type-safe API function
export async function getUser(id: string): Promise<User> {
  const response = await fetch(`/api/users/${id}`);
  const data = await response.json();
  return UserSchema.parse(data);
}

4. Generic Components

// Generic list component
interface ListProps<T> {
  items: T[];
  renderItem: (item: T, index: number) => React.ReactNode;
  keyExtractor: (item: T) => string;
  EmptyComponent?: React.ComponentType;
}

function List<T>({ 
  items, 
  renderItem, 
  keyExtractor, 
  EmptyComponent 
}: ListProps<T>) {
  if (items.length === 0 && EmptyComponent) {
    return <EmptyComponent />;
  }

  return (
    <ul>
      {items.map((item, index) => (
        <li key={keyExtractor(item)}>
          {renderItem(item, index)}
        </li>
      ))}
    </ul>
  );
}

5. Server Actions with Type Safety

// app/actions/user.actions.ts
'use server';

import { z } from 'zod';
import { revalidatePath } from 'next/cache';

const UpdateUserSchema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
});

export async function updateUser(
  userId: string,
  formData: FormData
): Promise<{ success: boolean; error?: string }> {
  try {
    const validatedData = UpdateUserSchema.parse({
      name: formData.get('name'),
      email: formData.get('email'),
    });

    await db.user.update({
      where: { id: userId },
      data: validatedData,
    });

    revalidatePath('/profile');
    return { success: true };
  } catch (error) {
    if (error instanceof z.ZodError) {
      return { success: false, error: error.errors[0].message };
    }
    return { success: false, error: 'Failed to update user' };
  }
}

πŸ”§ Installation

Prerequisites

  • Node.js 18+
  • npm/yarn/pnpm
  • Git

Setup

  1. Clone the repository

    git clone https://github.com/jefercort/react-ts-practice.git
    cd react-ts-practice
  2. Install dependencies

    npm install
    # or
    yarn install
    # or
    pnpm install
  3. Set up environment variables

    cp .env.example .env.local
  4. Run development server

    npm run dev
    # or
    yarn dev
    # or
    pnpm dev
  5. Open browser

    Navigate to http://localhost:3000

πŸ“ Available Scripts

# Development
npm run dev          # Start development server
npm run build        # Build for production
npm run start        # Start production server

# Type Checking
npm run type-check   # Run TypeScript compiler check
npm run lint         # Run ESLint
npm run lint:fix     # Fix ESLint errors

# Testing
npm run test         # Run tests
npm run test:watch   # Run tests in watch mode
npm run test:coverage # Generate coverage report

# Formatting
npm run format       # Format with Prettier
npm run format:check # Check formatting

πŸŽ“ Key Learnings

TypeScript Mastery

  • Type Safety: Eliminating runtime errors through compile-time checks
  • Type Inference: Leveraging TypeScript's powerful type inference
  • Generics: Building reusable, type-safe components
  • Utility Types: Using Partial, Required, Pick, Omit effectively
  • Discriminated Unions: Handling complex state with type safety

React Patterns

  • Compound Components: Building flexible, composable UIs
  • Render Props: Sharing logic between components
  • Higher-Order Components: Enhancing component functionality
  • Custom Hooks: Extracting and reusing stateful logic
  • Context with TypeScript: Type-safe context providers

Next.js Architecture

  • App Router: Modern routing with layouts and groups
  • Server Components: Optimal data fetching and rendering
  • Server Actions: Type-safe mutations without API routes
  • Middleware: Request interception and modification
  • Edge Runtime: Deploying to edge locations

πŸ† Best Practices

TypeScript

  • βœ… Enable strict mode in tsconfig.json
  • βœ… Avoid using any type
  • βœ… Use type inference where possible
  • βœ… Create shared type definitions
  • βœ… Validate external data with Zod

React

  • βœ… Use functional components with hooks
  • βœ… Implement error boundaries
  • βœ… Optimize with React.memo and useMemo
  • βœ… Follow accessibility guidelines
  • βœ… Write comprehensive tests

Next.js

  • βœ… Use Server Components by default
  • βœ… Implement proper loading states
  • βœ… Optimize images with next/image
  • βœ… Use dynamic imports for code splitting
  • βœ… Implement proper SEO with metadata

🚧 Future Enhancements

  • Add E2E tests with Playwright
  • Implement tRPC for end-to-end type safety
  • Add Storybook for component documentation
  • Implement Progressive Web App features
  • Add internationalization (i18n)
  • Implement real-time features with WebSockets
  • Add monitoring with Sentry
  • Implement feature flags
  • Add GraphQL with type generation
  • Create CI/CD pipeline with GitHub Actions

🀝 Contributing

Contributions are welcome! Please read the contributing guidelines before submitting PRs.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ‘¨β€πŸ’» Author

Kevin Cortes

πŸ™ Acknowledgments

  • Next.js team for the amazing framework
  • TypeScript team for making JavaScript type-safe
  • Vercel for hosting and deployment
  • The React community for continuous innovation

⭐ If you find this repository helpful, please give it a star!

πŸ”— Live Demo | πŸ“š Documentation | πŸ› Report Bug

About

A comprehensive collection of TypeScript patterns, best practices, and advanced React concepts implemented with Next.js 14. This repository demonstrates type-safe development, modern React patterns, and production-ready architectures.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published