Real World Example

Folder Structure of a Typed Backend

Large codebases at Razorpay, Swiggy or any NestJS shop split code into feature modules. Types live next to the code that owns them, shared types sit in a shared package, and type-only imports keep the runtime dependency graph clean.

src/
  shared/
    types.ts          export type Money, ApiResponse<T>, Paginated<T>
    errors.ts         export class AppError
  products/
    product.types.ts  export interface Product, CreateProductDto
    product.repo.ts   import type { Product } from "./product.types"
    product.service.ts
    index.ts          barrel: export * from "./product.service"
  orders/
    order.service.ts  import { ProductService } from "../products"
                      import type { Money } from "../shared/types"
  main.ts
// orders/order.service.ts
import type { Money } from "../shared/types";
import type { Product } from "../products/product.types";
import { AppError } from "../shared/errors";

export function orderTotal(items: { product: Product; qty: number }[]): Money {
  if (items.length === 0) throw new AppError("EMPTY_CART", "Cart is empty");
  return { amountPaise: items.reduce((s, i) => s + i.product.price * 100 * i.qty, 0), currency: "INR" };
}