ngodingdulu
Web & DatabaseTutorialPemula

TypeScript untuk Pemula: JavaScript yang Lebih Aman

TypeScript menangkap banyak kesalahan JavaScript sebelum kodenya dijalankan. Kamu akan memasangnya, memahami pesan errornya, dan menulis program keranjang belanja bertipe.

Oleh Afa Hernandes12 menit baca

Daftar isi

JavaScript membiarkan banyak kesalahan lolos sampai program dijalankan, dan kadang tetap lolos tanpa error sama sekali. Coba program kecil ini:

bug.js
function hitungTotal(harga, jumlah) {
return harga * jumlah;
}
const hargaDariForm = "18000"; // nilai dari <input> selalu berupa teks
console.log(hitungTotal(hargaDariForm, 2));
console.log(hitungTotal(hargaDariForm + 2000, 2));
console.log(hitungTotal(18000));
Output
36000
360004000
NaN

Baris pertama kebetulan benar. Baris kedua menghasilkan angka yang ngawur karena "18000" + 2000 menyambung teks menjadi "180002000". Baris ketiga lupa satu argumen dan menghasilkan NaN (Not a Number). Tidak ada satu pun pesan error. Di aplikasi sungguhan, kesalahan seperti ini baru ketahuan saat pelanggan protes totalnya salah.

TypeScript adalah JavaScript yang ditambah tipe data. Kamu menuliskan bahwa harga harus berupa angka, dan TypeScript memeriksa seluruh kodemu sebelum dijalankan. Ketiga kesalahan di atas langsung ketahuan. Di tutorial ini kamu akan memasang TypeScript, mengenal tipe-tipe yang paling sering dipakai, dan membuat program keranjang belanja yang tipenya lengkap.

Sebelum mulai

  • Sudah paham JavaScript modern: const, arrow function, array method, dan object. TypeScript hanya menambahkan tipe di atasnya.
  • Node.js versi LTS dari nodejs.org. Cek dengan node -v.
  • Diuji dengan Node 24 dan TypeScript 7.0.

Langkah 1: Siapkan proyek

Buat folder proyek, lalu pasang TypeScript di dalamnya:

Terminal
mkdir belajar-ts
cd belajar-ts
npm init -y
npm pkg set type=module
npm install --save-dev typescript
  • npm init -y membuat package.json, file yang mencatat informasi proyek dan paket yang dipakainya.
  • npm pkg set type=module membuat setiap file di proyek ini diperlakukan sebagai module JavaScript modern, sama seperti <script type="module"> di browser.
  • --save-dev menandai TypeScript sebagai alat untuk developer, bukan bagian dari program yang dijalankan pengguna.

Lalu buat file konfigurasi tsconfig.json:

belajar-ts/tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"strict": true,
"noEmit": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}

Opsi yang paling penting:

  • "strict": true menyalakan semua pemeriksaan yang ketat. Selalu nyalakan untuk proyek baru. Tanpa ini, banyak kesalahan dibiarkan lewat.
  • "noEmit": true artinya TypeScript hanya memeriksa, tidak menghasilkan file .js. Menjalankan programnya diserahkan ke Node.
  • "erasableSyntaxOnly": true melarang fitur TypeScript yang tidak bisa dijalankan langsung oleh Node. Penjelasannya ada di bagian error di bawah.

Perintah npx tsc --init juga bisa membuat tsconfig.json, tapi hasilnya lebih panjang dengan banyak opsi yang belum kamu perlukan. Versi pendek di atas cukup untuk tutorial ini.

Terakhir, tambahkan dua perintah pintas ke package.json:

Terminal
npm pkg set scripts.cek="tsc" scripts.start="node src/keranjang.ts"

Sekarang npm run cek memeriksa semua file TypeScript di proyek, dan npm start menjalankan program utamanya. Buat juga folder src untuk menyimpan kode.

Langkah 2: Tipe pertamamu

Tulis ulang hitungTotal dengan tipe:

belajar-ts/src/total.ts
function hitungTotal(harga: number, jumlah: number): number {
return harga * jumlah;
}
const hargaDariForm = "18000";
console.log(hitungTotal(hargaDariForm, 2));
console.log(hitungTotal(18000));

harga: number artinya parameter harga harus berupa angka. ): number setelah tanda kurung artinya function ini mengembalikan angka. Sekarang periksa:

Terminal
npm run cek
Output
src/total.ts(6,25): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
src/total.ts(7,13): error TS2554: Expected 2 arguments, but got 1.

Dua kesalahan yang tadi lolos diam-diam sekarang tertangkap, lengkap dengan lokasinya: (6,25) artinya baris 6, kolom 25. Di VS Code kamu bahkan tidak perlu menjalankan perintah apa pun. Bagian yang salah langsung diberi garis bergelombang merah saat kamu mengetik.

Perbaiki dengan mengubah teks menjadi angka secara eksplisit, dan hapus baris yang lupa argumen:

belajar-ts/src/total.ts
function hitungTotal(harga: number, jumlah: number): number {
return harga * jumlah;
}
const hargaDariForm = "18000";
console.log(hitungTotal(Number(hargaDariForm), 2));

Jalankan npm run cek lagi. Kalau tidak ada output, berarti tidak ada error. Lalu jalankan programnya:

Terminal
node src/total.ts
Output
36000

Node menjalankan, tsc memeriksa

Node versi baru bisa menjalankan file .ts secara langsung. Caranya dengan membuang semua penanda tipe, lalu menjalankan sisanya sebagai JavaScript biasa. Konsekuensinya penting: Node tidak memeriksa tipe. Kalau versi total.ts yang masih salah tadi dijalankan dengan node, hasilnya tetap 36000 dan NaN tanpa protes.

Jadi alurnya selalu dua langkah: npm run cek untuk memeriksa, lalu node untuk menjalankan. Di framework seperti Astro atau Next.js, pemeriksaan ini biasanya dijalankan otomatis saat build.

Langkah 3: Tipe dasar dan inferensi

belajar-ts/src/dasar.ts
let nama: string = "Sari";
let umur: number = 21;
let aktif: boolean = true;
let hobi: string[] = ["ngopi", "ngoding"];
let kota = "Bandung"; // TypeScript menyimpulkan tipenya: string
console.log(nama, umur, aktif, hobi, kota);
Tipe Isi Contoh
string teks "Sari"
number angka, bulat maupun desimal 21, 1.62
boolean benar atau salah true, false
string[] array berisi teks ["ngopi", "ngoding"]
null sengaja dikosongkan null

Perhatikan baris let kota = "Bandung". Tipenya tidak ditulis, tapi TypeScript menyimpulkannya sendiri dari nilai awalnya. Ini disebut inferensi tipe. Kalau nanti kamu menulis kota = 2026;, TypeScript tetap menolak:

Output
error TS2322: Type 'number' is not assignable to type 'string'.

Karena itu, kamu tidak perlu menulis tipe di semua tempat. Kebiasaan yang umum: tulis tipe di parameter function dan di bentuk data (bagian berikutnya), lalu biarkan TypeScript menyimpulkan sisanya.

Langkah 4: Bentuk data dengan interface

Data di aplikasi web kebanyakan berupa object. interface mendeskripsikan bentuknya: properti apa saja yang ada dan apa tipenya.

interface Produk {
id: number;
nama: string;
harga: number; // dalam rupiah, tanpa desimal
diskon?: number; // opsional, dalam persen
}
const kopiSusu: Produk = { id: 1, nama: "Kopi susu", harga: 18000 };

Tanda ? setelah diskon artinya properti itu opsional: boleh ada, boleh tidak. Properti lainnya wajib. Lupa satu properti, atau salah ketik nama method, langsung ketahuan:

const teh: Produk = { id: 3, nama: "Teh" };
console.log(kopiSusu.nama.toUppercase());
Output
error TS2741: Property 'harga' is missing in type '{ id: number; nama: string; }' but required in type 'Produk'.
error TS2551: Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?

Bonusnya: setelah interface ditulis, VS Code tahu persis isi setiap object. Ketik kopiSusu. dan editor langsung menawarkan id, nama, harga, dan diskon.

Langkah 5: Pilihan nilai dengan union type

Status pesanan hanya boleh salah satu dari beberapa nilai. Dengan tanda | (dibaca “atau”), kamu bisa membuat tipe yang membatasi pilihannya:

type Status = "draft" | "dibayar" | "dikirim";
let status: Status = "draft";
status = "dibayar";
status = "dibayr";
Output
error TS2820: Type '"dibayr"' is not assignable to type 'Status'. Did you mean '"dibayar"'?

Di JavaScript biasa, salah ketik "dibayr" akan lolos dan baru ketahuan saat pesanan tidak pernah muncul di daftar “dibayar”. Di TypeScript, kesalahan itu tertangkap bahkan sebelum kamu menyimpan file.

type membuat nama baru untuk sebuah tipe. Union type juga bisa menggabungkan tipe yang berbeda, misalnya string | null untuk teks yang boleh kosong.

Langkah 6: Menangani nilai yang bisa kosong

Salah satu error paling sering di JavaScript adalah memakai nilai yang ternyata null. Dengan strict, TypeScript memaksa kamu memikirkannya:

function panjangCatatan(catatan: string | null): number {
return catatan.length;
}
Output
error TS18047: 'catatan' is possibly 'null'.

Solusinya, periksa dulu:

belajar-ts/src/catatan.ts
function panjangCatatan(catatan: string | null): number {
if (catatan === null) {
return 0;
}
return catatan.length;
}
console.log(panjangCatatan("Gula sedikit"));
console.log(panjangCatatan(null));
Output
12
0

Setelah if (catatan === null) return …, TypeScript tahu bahwa di baris berikutnya catatan pasti berupa string. Proses mempersempit tipe seperti ini disebut narrowing. Hal yang sama berlaku untuk properti opsional: produk.diskon bertipe number | undefined, jadi kamu harus memeriksanya sebelum dipakai untuk menghitung.

Langkah 7: Program keranjang belanja

Sekarang gabungkan semuanya. Program ini menghitung pesanan di kedai Kopi Senja, sama seperti keranjang di tutorial JavaScript, tapi kali ini setiap data punya tipe yang jelas:

belajar-ts/src/keranjang.ts
type Status = "draft" | "dibayar" | "dikirim";
interface Produk {
id: number;
nama: string;
harga: number; // dalam rupiah, tanpa desimal
diskon?: number; // opsional, dalam persen
}
interface ItemKeranjang {
produk: Produk;
jumlah: number;
}
interface Pesanan {
pelanggan: string;
items: ItemKeranjang[];
status: Status;
catatan: string | null;
}
function hargaSetelahDiskon(produk: Produk): number {
if (produk.diskon === undefined) {
return produk.harga;
}
return Math.round(produk.harga * (1 - produk.diskon / 100));
}
function totalPesanan(pesanan: Pesanan): number {
return pesanan.items.reduce(
(total, item) => total + hargaSetelahDiskon(item.produk) * item.jumlah,
0,
);
}
function formatRupiah(nilai: number): string {
return "Rp" + nilai.toLocaleString("id-ID");
}
function labelStatus(status: Status): string {
switch (status) {
case "draft":
return "Belum dibayar";
case "dibayar":
return "Sedang dikemas";
case "dikirim":
return "Dalam perjalanan";
}
}
const kopiSusu: Produk = { id: 1, nama: "Kopi susu", harga: 18000 };
const croissant: Produk = { id: 2, nama: "Croissant", harga: 25000, diskon: 20 };
const pesanan: Pesanan = {
pelanggan: "Sari",
items: [
{ produk: kopiSusu, jumlah: 2 },
{ produk: croissant, jumlah: 1 },
],
status: "dibayar",
catatan: null,
};
console.log(`Pesanan ${pesanan.pelanggan}: ${labelStatus(pesanan.status)}`);
for (const item of pesanan.items) {
const subtotal = hargaSetelahDiskon(item.produk) * item.jumlah;
console.log(`- ${item.jumlah}x ${item.produk.nama}: ${formatRupiah(subtotal)}`);
}
console.log(`Total: ${formatRupiah(totalPesanan(pesanan))}`);
console.log(`Catatan: ${pesanan.catatan ?? "-"}`);

npm run cek memeriksa semua file di proyek. Kalau ada file latihan dari langkah sebelumnya yang masih berisi kode yang sengaja salah, perbaiki atau hapus dulu. Lalu periksa dan jalankan:

Terminal
npm run cek
npm start
Output
Pesanan Sari: Sedang dikemas
- 2x Kopi susu: Rp36.000
- 1x Croissant: Rp20.000
Total: Rp56.000
Catatan: -

Beberapa hal yang patut diperhatikan:

  • Interface bisa bersarang. Pesanan berisi array ItemKeranjang, dan setiap ItemKeranjang berisi Produk. Bentuk datanya terbaca dari atas tanpa perlu menebak.
  • labelStatus tidak butuh default. TypeScript tahu Status hanya punya tiga kemungkinan dan ketiganya sudah ditangani. Kalau suatu hari kamu menambah status "dibatalkan" tapi lupa menambah case-nya, npm run cek langsung protes: error TS2366: Function lacks ending return statement and return type does not include 'undefined'.
  • Parameter di dalam reduce tidak perlu diberi tipe. TypeScript menyimpulkan item sebagai ItemKeranjang dari tipe pesanan.items.

type atau interface?

Untuk mendeskripsikan bentuk object, keduanya hampir sama. Ini juga sah:

belajar-ts/src/tipe-alias.ts
type Produk = {
id: number;
nama: string;
harga: number;
diskon?: number;
};

Aturan praktis yang dipakai banyak tim: interface untuk bentuk object, type untuk union dan hal lain seperti type Status = "draft" | "dibayar". Yang lebih penting dari pilihannya adalah konsisten dalam satu proyek.

Error yang sering muncul

error TS2345: Argument of type ‘string’ is not assignable to parameter of type ‘number’.

Kamu mengirim teks ke parameter yang meminta angka. Sering terjadi dengan nilai dari form atau URL. Ubah dulu dengan Number(nilai), lalu pastikan hasilnya bukan NaN sebelum dipakai.

error TS2554: Expected 2 arguments, but got 1.

Jumlah argumen tidak sesuai dengan parameter function. Lengkapi argumennya, atau jadikan parameternya opsional dengan ? kalau memang boleh tidak diisi.

error TS2741: Property ‘harga’ is missing in type …

Object yang kamu buat tidak punya properti yang diwajibkan oleh interface-nya. Tambahkan propertinya, atau beri ? di interface kalau properti itu memang opsional.

error TS18048: ‘produk.diskon’ is possibly ‘undefined’.

Kamu memakai properti opsional tanpa memeriksanya. Tambahkan pemeriksaan seperti di hargaSetelahDiskon, atau beri nilai cadangan dengan produk.diskon ?? 0.

error TS7006: Parameter ‘data’ implicitly has an ‘any’ type.

Parameter function belum diberi tipe, sehingga TypeScript tidak bisa memeriksanya. Tuliskan tipenya, misalnya (data: Produk). Jangan menambal dengan any, karena any mematikan semua pemeriksaan untuk nilai itu.

error TS1294: This syntax is not allowed when ‘erasableSyntaxOnly’ is enabled.

Biasanya muncul saat memakai enum. Node tidak bisa menjalankan enum dengan cara membuang tipe saja, dan kalau tetap dijalankan, hasilnya SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode. Ganti dengan union type seperti type Status = "draft" | "dibayar", yang hasilnya sama dan lebih ringkas.

error TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline.

Kamu menjalankan npx tsc nama-file.ts. Kalau ada tsconfig.json, jalankan npx tsc (atau npm run cek) tanpa nama file, supaya pengaturan di tsconfig.json ikut dipakai.

Langkah berikutnya: rilis dan amankan

Satu hal yang sering disalahpahami: tipe TypeScript hilang saat program berjalan. TypeScript hanya memeriksa kode yang kamu tulis. Data yang datang dari luar, seperti isi form, respons API, atau file JSON, tidak ikut diperiksa saat program berjalan. Kalau API mengirim harga: "18000" padahal interface-mu bilang number, TypeScript tidak akan tahu. Data dari luar tetap harus divalidasi, terutama di server. Kebiasaan ini akan banyak dipakai saat membuat API di level berikutnya, dan alasannya dijelaskan di OWASP Top 10.

Untuk merilis, browser tidak bisa menjalankan file .ts secara langsung. Framework modern seperti Astro dan Next.js mengurus pengubahan ke JavaScript saat build, dan hasilnya bisa di-deploy seperti biasa lewat deploy pertama ke Cloudflare Pages. Simpan proyekmu di GitHub dengan Git, dan pastikan folder node_modules masuk .gitignore.

Pertanyaan yang sering diajukan

Apakah TypeScript menggantikan JavaScript?

Tidak. TypeScript adalah JavaScript plus tipe. Semua yang kamu pelajari di JavaScript tetap berlaku, dan setelah tipe dibuang, yang berjalan adalah JavaScript biasa.

Apakah kode TypeScript berjalan lebih cepat?

Tidak. Setelah tipe dibuang, kodenya sama dengan JavaScript. Keuntungan TypeScript ada di saat menulis kode: kesalahan ketahuan lebih awal, dan editor bisa memberi saran yang jauh lebih akurat.

Bolehkah memakai any saat bingung menentukan tipe?

Sebaiknya tidak. any membuat TypeScript berhenti memeriksa nilai itu, sehingga kamu kembali ke JavaScript tanpa pengaman. Kalau tipe datanya memang belum diketahui, pakai unknown, yang memaksa kamu memeriksa isinya dulu sebelum dipakai.

Perlu belajar TypeScript kalau sudah paham JavaScript?

Kalau kamu ingin bekerja dengan framework modern atau di tim, ya. Banyak proyek dan contoh di dokumentasi framework sekarang ditulis dalam TypeScript. Kabar baiknya, dasar yang ada di tutorial ini sudah cukup untuk membaca sebagian besar kode TypeScript sehari-hari.

Kesimpulan

TypeScript menambahkan tipe ke JavaScript supaya banyak kesalahan, seperti salah tipe, argumen kurang, salah ketik, dan nilai yang ternyata kosong, ketahuan sebelum kode dijalankan. Dengan strict, interface, union type, dan narrowing, kamu sudah memegang alat yang paling sering dipakai. Ingat alurnya: tsc memeriksa, Node menjalankan.

Dengan ini Level 1 jalur Web Developer Modern selesai: HTML dan CSS, JavaScript, dan TypeScript. Level berikutnya membahas cara berpikir dalam komponen dan memilih framework modern.

Bagikan:WhatsAppTelegramXFacebook
Ilustrasi jendela browser berisi tiga tahap belajar web: fondasi, komponen dan framework, lalu full-stack, diakhiri bendera online
WebRoadmap

Roadmap Web Developer 2026 untuk Pemula

Tiga level berurutan, dari halaman HTML pertama sampai aplikasi full-stack yang online. Lengkap dengan urutan belajar dan tanda kapan kamu siap naik level.

23 Oktober 20266 mnt

Ilustrasi dua kartu bersebelahan: kartu kiri berisi daftar alat lama seperti XAMPP, mysql_query, jQuery, dan FTP, kartu kanan berisi padanan modernnya seperti PHP 8, prepared statement, fetch, dan git push
WebKonsep

Apa yang Berubah di Dunia Web Sejak Era XAMPP

Kalau terakhir ngoding web dengan XAMPP, PHP native, jQuery, dan FTP, ini peta yang berubah, yang tetap sama, dan urutan mengejarnya tanpa membuang pengalamanmu.

6 November 202610 mnt

Ilustrasi pohon folder proyek PHP berisi composer.json, src, dan vendor, dengan baris require vendor/autoload.php yang menghubungkan ke beberapa file class
WebTutorial

PHP Modern: Versi 8, Composer, dan Autoload

Dari include satu per satu ke autoload, dari fungsi tanpa tipe ke class yang ketat. Kamu akan membuat program kasir kecil dengan fitur PHP 8 dan Composer.

9 November 202615 mnt

Enter bukaEsc tutupHalaman pencarian