Mini Project TypeScript: Aplikasi Inventori Barang dengan Penyimpanan Data Lokal dan Validasi Otomatis

By | 22 October 2025

Setelah menguasai dasar-dasar TypeScript dan membuat proyek CRUD sederhana, kini saatnya naik ke tahap berikutnya melalui mini project TypeScript lanjutan. Pada tahap ini, Anda akan mempelajari bagaimana menerapkan konsep TypeScript ke dalam aplikasi yang lebih nyata, yaitu aplikasi inventori barang yang dilengkapi dengan penyimpanan data lokal dan validasi otomatis.

Melalui latihan ini, Anda akan memahami penerapan Object-Oriented Programming (OOP), modularisasi proyek, serta bagaimana TypeScript membantu menghindari error melalui sistem tipe yang kuat. Dengan menambahkan penyimpanan data lokal dan validasi otomatis, aplikasi Anda akan terasa lebih realistis dan siap dikembangkan menjadi aplikasi manajemen stok yang lebih kompleks.

Tujuan Mini Project TypeScript Lanjutan

Dalam proyek ini, Anda akan belajar:

  • Mengelola data produk dan stok dengan class dan interface.

  • Menyimpan data secara lokal menggunakan file JSON (simulasi database).

  • Membuat sistem validasi otomatis untuk mencegah input tidak valid.

  • Menerapkan modularisasi proyek dengan struktur folder yang rapi.

Struktur Proyek

Berikut struktur proyek yang akan kita gunakan:

inventory-project-ts/
│
├── src/
│   ├── models/
│   │   └── Item.ts
│   ├── services/
│   │   ├── InventoryService.ts
│   │   └── StorageService.ts
│   ├── utils/
│   │   └── Validator.ts
│   ├── main.ts
│
├── data/
│   └── inventory.json
│
├── tsconfig.json
└── package.json

Langkah 1: Membuat Model Item

Model Item akan merepresentasikan barang dalam inventori.

File: src/models/Item.ts

export interface IItem {
  id: number;
  name: string;
  quantity: number;
  price: number;
}

export class Item implements IItem {
  constructor(
    public id: number,
    public name: string,
    public quantity: number,
    public price: number
  ) {}
}

Interface IItem mendefinisikan tipe data, sementara class Item berfungsi sebagai blueprint objek barang.

Langkah 2: Menambahkan Validasi Otomatis

Kita buat helper untuk memvalidasi input sebelum disimpan.

File: src/utils/Validator.ts

import { IItem } from "../models/Item";

export class Validator {
  static validateItem(item: IItem): void {
    if (!item.name || item.name.trim() === "") {
      throw new Error("Nama barang tidak boleh kosong.");
    }
    if (item.quantity < 0) {
      throw new Error("Jumlah stok tidak boleh negatif.");
    }
    if (item.price <= 0) {
      throw new Error("Harga harus lebih dari 0.");
    }
  }
}

Dengan validasi ini, setiap data yang masuk akan diperiksa terlebih dahulu, sehingga kesalahan input dapat dicegah sebelum disimpan.

Langkah 3: Membuat Layanan Penyimpanan Lokal

Kita akan menyimpan data inventori ke file JSON menggunakan fs dari Node.js.

File: src/services/StorageService.ts

import { readFileSync, writeFileSync, existsSync } from "fs";

export class StorageService {
  private filePath: string;

  constructor(filePath: string) {
    this.filePath = filePath;

    if (!existsSync(filePath)) {
      writeFileSync(filePath, "[]", "utf-8");
    }
  }

  readData(): any[] {
    const data = readFileSync(this.filePath, "utf-8");
    return JSON.parse(data);
  }

  writeData(data: any[]): void {
    writeFileSync(this.filePath, JSON.stringify(data, null, 2), "utf-8");
  }
}

Class ini berfungsi sebagai pengelola file JSON yang bertugas membaca dan menulis data secara lokal.

Langkah 4: Membuat Layanan Inventori

Berikut class utama yang mengatur proses CRUD dan validasi data.

File: src/services/InventoryService.ts

import { Item } from "../models/Item";
import { StorageService } from "./StorageService";
import { Validator } from "../utils/Validator";

export class InventoryService {
  private storage: StorageService;
  private items: Item[];

  constructor(storagePath: string) {
    this.storage = new StorageService(storagePath);
    this.items = this.storage.readData();
  }

  addItem(item: Item): void {
    Validator.validateItem(item);
    this.items.push(item);
    this.storage.writeData(this.items);
    console.log(`✅ Barang "${item.name}" berhasil ditambahkan.`);
  }

  getAllItems(): Item[] {
    return this.items;
  }

  updateItem(id: number, data: Partial<Item>): void {
    const item = this.items.find(i => i.id === id);
    if (!item) {
      console.log("❌ Barang tidak ditemukan!");
      return;
    }

    Object.assign(item, data);
    Validator.validateItem(item);
    this.storage.writeData(this.items);
    console.log(` Barang "${item.name}" berhasil diperbarui.`);
  }

  deleteItem(id: number): void {
    const index = this.items.findIndex(i => i.id === id);
    if (index === -1) {
      console.log("❌ Barang tidak ditemukan!");
      return;
    }

    const deleted = this.items.splice(index, 1);
    this.storage.writeData(this.items);
    console.log(`️ Barang "${deleted[0].name}" berhasil dihapus.`);
  }
}

Langkah 5: Menjalankan Aplikasi

File: src/main.ts

import { Item } from "./models/Item";
import { InventoryService } from "./services/InventoryService";

const inventory = new InventoryService("./data/inventory.json");

inventory.addItem(new Item(1, "Mouse Wireless", 25, 150000));
inventory.addItem(new Item(2, "Keyboard Mechanical", 10, 450000));

console.log(" Daftar Barang:", inventory.getAllItems());

inventory.updateItem(2, { price: 400000 });

inventory.deleteItem(1);

console.log(" Barang Tersisa:", inventory.getAllItems());

Menjalankan Proyek

Instal TypeScript dan inisialisasi proyek:

npm install -g typescript
tsc --init

Kompilasi dan jalankan:

tsc
node dist/main.js

Hasil Output

✅ Barang "Mouse Wireless" berhasil ditambahkan.
✅ Barang "Keyboard Mechanical" berhasil ditambahkan.
 Daftar Barang: [Item {...}, Item {...}]
 Barang "Keyboard Mechanical" berhasil diperbarui.
️ Barang "Mouse Wireless" berhasil dihapus.
 Barang Tersisa: [Item {...}]

Pengembangan Lebih Lanjut

Anda dapat memperluas mini project TypeScript ini dengan:

  • Menambahkan fitur pencarian barang berdasarkan nama.

  • Menyertakan sistem kategori produk.

  • Menambahkan laporan total nilai stok.

  • Mengintegrasikan dengan database seperti SQLite atau MongoDB.

Kesimpulan

Proyek Mini Project TypeScript lanjutan ini memperkenalkan cara membangun aplikasi inventori barang dengan fitur CRUD, penyimpanan data lokal, dan validasi otomatis. Melalui latihan ini, Anda tidak hanya berlatih menulis kode yang rapi dan terstruktur, tetapi juga memahami bagaimana TypeScript membantu menjaga integritas data dan mencegah error sejak tahap pengembangan.

Dengan menguasai proyek ini, Anda siap melangkah ke level berikutnya — membangun aplikasi backend nyata menggunakan Express + TypeScript dengan arsitektur RESTful API yang profesional.