Careeroza
Real World Example
CRUD DTOs From One Entity
Backend teams (NestJS services at fintechs, Next.js admin panels) derive all their request and response types from one entity type. Add a field once and every DTO updates.
Example
type Product = {
id: number;
name: string;
description: string;
price: number;
stock: number;
category: "electronics" | "books" | "fashion";
createdAt: string;
};
type CreateProductDto = Omit<Product, "id" | "createdAt">;
type UpdateProductDto = Partial<CreateProductDto>;
type ProductListItem = Pick<Product, "id" | "name" | "price">;
type StockByCategory = Record<Product["category"], number>;
const db: Product[] = [];
let nextId = 1;
function create(dto: CreateProductDto): Product {
const p: Product = { ...dto, id: nextId++, createdAt: "2026-01-15T10:00:00Z" };
db.push(p);
return p;
}
function update(id: number, dto: UpdateProductDto): Readonly<Product> | undefined {
const p = db.find((x) => x.id === id);
return p && Object.assign(p, dto);
}
const list = (): ProductListItem[] => db.map(({ id, name, price }) => ({ id, name, price }));
create({ name: "Kettle", description: "1.5L", price: 1299, stock: 10, category: "electronics" });
create({ name: "Atomic Habits", description: "Book", price: 499, stock: 40, category: "books" });
update(1, { price: 1199 });
const stock: StockByCategory = { electronics: 0, books: 0, fashion: 0 };
db.forEach((p) => (stock[p.category] += p.stock));
console.log(list());
console.log(stock);Output
[
{ id: 1, name: 'Kettle', price: 1199 },
{ id: 2, name: 'Atomic Habits', price: 499 }
]
{ electronics: 10, books: 40, fashion: 0 }