All TypeScript types are defined in frontend/types/index.ts. Types match backend API response structure and provide type safety across the frontend application.
Purpose: Guidance for creating TypeScript type definitions following existing patterns from frontend/types/index.ts.
All TypeScript types are defined in frontend/types/index.ts. Types match backend API response structure and provide type safety across the frontend application.
frontend/types/index.tsexport interface User {
id: string;
email: string;
name: string;
createdAt?: string;
updatedAt?: string;
}
export interface UserCredentials {
email: string;
password: string;
}
export interface UserSignupData extends UserCredentials {
name: string;
}
Pattern:
interface for object types?extends for type inheritanceexport type TaskStatus = "pending" | "completed";
export type TaskPriority = "low" | "medium" | "high";
export interface Task {
id: number;
user_id: string;
title: string;
description?: string;
completed: boolean;
priority: TaskPriority;
due_date?: string;
tags: string[];
created_at: string;
updated_at: string;
}
export interface TaskFormData {
title: string;
description?: string;
priority?: TaskPriority;
due_date?: string;
tags?: string[];
}
export interface TaskQueryParams {
status?: "all" | "pending" | "completed";
sort?: "created" | "title" | "updated" | "priority" | "due_date";
search?: string;
page?: number;
limit?: number;
}
Pattern:
type for union types (string literals)interface for object typesuser_id, due_date, created_at)export interface ApiResponse<T = unknown> {
data?: T;
success: boolean;
message?: string;
error?: {
code: string;
message: string;
details?: unknown;
};
}
export interface PaginatedResponse<T> {
data: T[];
meta: {
total: number;
page: number;
limit: number;
totalPages: number;
};
}
Pattern:
<T> for reusable structures<T = unknown>)success boolean flagdata, message, and error fieldsmeta objectexport interface AuthResponse {
success: boolean;
token: string;
user: User;
}
export interface Session {
user: User;
token: string;
expiresAt: number;
}
Pattern:
success booleantoken stringuser object (User type)expiresAt timestamp for sessionexport interface AppError {
message: string;
code?: string;
statusCode?: number;
field?: string;
}
export interface FormErrors {
[key: string]: string | undefined;
}
Pattern:
interface for error objects?[key: string] for dynamic object types (FormErrors)export type LoadingState = "idle" | "loading" | "success" | "error";
export type ToastType = "success" | "error" | "warning" | "info";
export interface ToastMessage {
id: string;
type: ToastType;
message: string;
duration?: number;
}
Pattern:
type for union types (string literals)interface for object typesid for unique identification?export type ExportFormat = "csv" | "json";
export interface ImportResult {
imported: number;
errors: number;
errorDetails?: string[];
}
Pattern:
type for union types (string literals)interface for result objectsUser, Task, ApiResponseTaskFormData, UserSignupDataTaskStatus, TaskPriority, LoadingStateToastType, ExportFormatTaskItemProps, ProtectedRoutePropsinterface TaskItemProps { task: Task; }TaskFormData, UserSignupDatainterface TaskFormData { title: string; description?: string; }TaskQueryParamsinterface TaskQueryParams { status?: "all" | "pending" | "completed"; }Backend (snake_case) → Frontend (camelCase for form data, snake_case for API response)
// Backend API response (matches backend exactly)
export interface Task {
id: number;
user_id: string; // snake_case from backend
title: string;
due_date?: string; // snake_case from backend
created_at: string; // snake_case from backend
updated_at: string; // snake_case from backend
}
// Frontend form data (camelCase for easier use)
export interface TaskFormData {
title: string;
dueDate?: string; // camelCase for frontend
tags?: string[];
}
Pattern:
// Backend API response (all fields from backend)
export interface Task {
id: number; // Required (from backend)
user_id: string; // Required (from backend)
title: string; // Required (from backend)
description?: string; // Optional (from backend)
completed: boolean; // Required (from backend)
priority: TaskPriority; // Required (from backend)
due_date?: string; // Optional (from backend)
tags: string[]; // Required (from backend, can be empty array)
created_at: string; // Required (from backend)
updated_at: string; // Required (from backend)
}
// Frontend form data (only fields user can edit)
export interface TaskFormData {
title: string; // Required (user must provide)
description?: string; // Optional
priority?: TaskPriority; // Optional (has default)
due_date?: string; // Optional
tags?: string[]; // Optional (can be empty array)
}
Pattern:
??interface for Objectsexport interface User {
id: string;
email: string;
}
When to use: Object types with properties
type for Unions, Intersections, or Aliasesexport type TaskStatus = "pending" | "completed";
export type TaskPriority = "low" | "medium" | "high";
When to use: Union types, intersections, or type aliases
export interface ApiResponse<T = unknown> {
data?: T;
success: boolean;
}
When to use: Reusable structures that work with different types
?export interface Task {
title: string; // Required
description?: string; // Optional
}
When to use: Fields that may not exist
export interface Category {
id: number;
user_id: string;
name: string;
color?: string;
created_at: string;
updated_at: string;
}
export interface CategoryFormData {
name: string;
color?: string;
}
export interface CategoryQueryParams {
search?: string;
page?: number;
limit?: number;
}
async getCategories(
userId: string,
queryParams?: CategoryQueryParams
): Promise<ApiResponse<PaginatedResponse<Category>>> {
// Implementation
}
specs/002-frontend-todo-app/spec.md - Entity definitionsspecs/002-frontend-todo-app/plan.md - API contracts with typesfrontend/types/index.ts - Complete type definitionsinterface for object typestype for union types (string literals)<T> for reusable structures?<T = unknown>)