← back to StudentLoanTracker

src/lib/calculators/types.ts

70 lines

/**
 * Shared types for all student loan calculators.
 *
 * Design: every calculator accepts a `LoanInputs` object and returns
 * a plan-specific result that extends `PlanResult`. This keeps the
 * signature uniform so the comparison engine can iterate over all plans.
 */

// ── Filing status for tax-related calculations ─────────────────────
export type FilingStatus = 'single' | 'married_filing_jointly' | 'married_filing_separately' | 'head_of_household';

// ── Employer type for PSLF eligibility ─────────────────────────────
export type EmployerType = 'government' | 'nonprofit' | 'for_profit' | 'unknown';

// ── Core input that every calculator accepts ───────────────────────
export interface LoanInputs {
  totalBalance: number;          // Current total loan balance ($)
  weightedRate: number;          // Weighted average interest rate (decimal, e.g. 0.065 = 6.5%)
  agi: number;                   // Adjusted gross income ($)
  familySize: number;            // Household size (1+)
  filingStatus: FilingStatus;
  state: string;                 // 2-letter state code (for future state-specific rules)
  spouseIncome?: number;         // Spouse AGI if married filing jointly ($)
  // Advanced inputs
  individualLoans?: IndividualLoan[];
  qualifyingPayments?: number;   // PSLF: payments already made toward 120
  employerType?: EmployerType;
  yearsInRepayment?: number;     // Years already in repayment
}

export interface IndividualLoan {
  name: string;                  // e.g. "Direct Subsidized #1"
  balance: number;
  rate: number;                  // Decimal
  type: 'subsidized' | 'unsubsidized' | 'grad_plus' | 'parent_plus' | 'consolidated' | 'other';
  originalBalance?: number;
  disbursementDate?: string;     // ISO date
}

// ── Standard result shape ──────────────────────────────────────────
export interface PlanResult {
  planName: string;
  monthlyPayment: number;        // First-year monthly payment ($)
  totalPaid: number;             // Sum of all payments over repayment period ($)
  totalInterest: number;         // Total interest paid ($)
  forgivenessAmount: number;     // Amount forgiven at end (0 if none)
  forgivenessMonths: number;     // Months until forgiveness (240, 300, or 120 for PSLF)
  repaymentMonths: number;       // Actual months of payments
  discretionaryIncome: number;   // Computed DI for transparency
  povertyGuideline: number;      // Poverty line used
  paymentSchedule?: MonthlySnapshot[]; // Optional month-by-month breakdown
}

export interface MonthlySnapshot {
  month: number;
  payment: number;
  principal: number;
  interest: number;
  balance: number;
}

// ── Comparison result ──────────────────────────────────────────────
export interface ComparisonResult {
  inputs: LoanInputs;
  plans: PlanResult[];
  recommended: string;           // planName of lowest total cost
  lowestMonthly: string;         // planName of lowest monthly payment
  fastestPayoff: string;         // planName of shortest repayment
}