kodingup.camp

Beranda/TypeScript Mastery

Tipe Dasar

Modul 3 dari 124 menit bacaBasic Types

Isi modul

    Kenapa ini penting

    Tipe dasar adalah "kosakata" TypeScript. Sama seperti belajar bahasa asing dimulai dari kata benda dan kata kerja, semua tipe rumit nanti (generics, utility types, tipe props React) dibangun dari tipe-tipe dasar ini. Kalau kamu paham betul perbedaan any dan unknown, atau kapan TypeScript bisa menebak tipe sendiri, kamu akan menulis kode yang lebih ringkas sekaligus lebih aman.

    Analoginya seperti wadah di dapur: toples gula, botol kecap, kotak telur. Setiap wadah dibuat untuk isi tertentu. Kalau kamu menuang kecap ke toples gula, kekacauan baru ketahuan saat seseorang membuat teh. Tipe adalah label di wadah itu, dan TypeScript adalah orang yang mencegahmu menuang isi yang salah.

    Konsep inti

    Tipe primitif

    Tipe Contoh nilai Catatan
    string "Sari", `Halo ${nama}` Semua teks
    number 42, 3.14, NaN Bilangan bulat dan desimal sama-sama number
    boolean true, false
    bigint 9007199254740993n Angka sangat besar
    symbol Symbol("id") Jarang dipakai di aplikasi biasa
    null null "Sengaja kosong"
    undefined undefined "Belum diisi"

    Perhatikan huruf kecil: string, bukan String. String (kapital) adalah object pembungkus di JavaScript dan hampir tidak pernah kamu perlukan sebagai tipe.

    Inferensi tipe

    Kamu tidak wajib menulis tipe di mana-mana. TypeScript menebak (infer) tipe dari nilai awal:

    let kota = "Bandung"; // TypeScript menyimpulkan: string
    kota = 123; // ❌ error TS2322: Type 'number' is not assignable to type 'string'.
    

    Aturan praktis: biarkan TypeScript menebak untuk variabel lokal yang langsung diisi, dan tulis tipe secara eksplisit di batas: parameter function, nilai kembalian function publik, dan data dari luar. Ada juga perbedaan halus antara let dan const: const status = "aktif" bertipe literal "aktif" (karena tidak bisa diubah), sedangkan let status = "aktif" bertipe string.

    Array dan tuple

    Array ditulis tipe[] atau Array<tipe>. Keduanya sama; tim biasanya memilih satu gaya.

    const nilai: number[] = [80, 90, 75];
    const nama: Array<string> = ["Andi", "Budi"];
    

    Tuple adalah array dengan panjang dan tipe per posisi yang tetap. Contoh paling akrab bagi developer React: useState mengembalikan tuple [nilai, fungsiPengubah].

    const koordinat: [number, number] = [-6.2, 106.8]; // lintang, bujur
    const entri: [string, number] = ["apel", 3];
    

    Tuple boleh diberi label agar mudah dibaca: type Rentang = [awal: number, akhir: number];.

    any vs unknown

    Keduanya bisa menampung nilai apa pun. Bedanya ada di apa yang boleh kamu lakukan sesudahnya:

    any unknown
    Boleh diisi apa saja Ya Ya
    Boleh langsung dipakai (x.toUpperCase()) Ya, tanpa diperiksa Tidak, harus dipersempit dulu
    Keamanan Mematikan pemeriksaan Aman
    Kapan dipakai Darurat, migrasi sementara Data dari luar: JSON.parse, catch (err), respons API

    Analogi: any itu seperti kotak tanpa label yang langsung kamu tuang ke masakan. unknown itu kotak tanpa label yang harus kamu cium dan cicipi dulu sebelum dipakai. Di mode strict, variabel err di catch (err) bertipe unknown, bukan any.

    void dan never

    null dan undefined di mode strict

    Dengan strictNullChecks (bagian dari strict), null dan undefined bukan anggota otomatis tipe lain. let nama: string = null adalah error. Kalau sebuah nilai memang boleh kosong, katakan secara jujur: string | null. Ini yang membuat TypeScript bisa memperingatkan possibly 'undefined'.

    Type assertion (as) secukupnya

    nilai as Tipe berarti "percayalah, saya tahu tipenya". TypeScript tidak memeriksa kebenarannya di runtime. Pakai seminimal mungkin; lebih baik persempit dengan pemeriksaan sungguhan.

    Contoh kode

    // tipe-dasar.ts
    
    // 1. Primitif dengan inferensi
    let namaToko = "Warung Sari";   // string
    let jumlahMeja = 12;             // number
    let buka = true;                 // boolean
    const kategori = "kuliner";      // tipe literal "kuliner" karena const
    
    namaToko = "Warung Sari Rasa";   // boleh, masih string
    jumlahMeja = "dua belas"; // ❌ error TS2322: Type 'string' is not assignable to type 'number'.
    
    // 2. Array dan tuple
    const hargaMenu: number[] = [15000, 20000, 18000];
    hargaMenu.push("gratis"); // ❌ error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
    
    const lokasi: [kota: string, kodePos: number] = ["Bandung", 40115];
    const [kota, kodePos] = lokasi;
    console.log(kota.toUpperCase(), kodePos.toFixed(0)); // → BANDUNG 40115
    
    // 3. void
    function catat(pesan: string): void {
      console.log(`[LOG] ${pesan}`);
    }
    catat(`${namaToko} buka: ${buka}`); // → [LOG] Warung Sari Rasa buka: true
    
    // 4. never: function yang tidak pernah selesai normal
    function gagal(pesan: string): never {
      throw new Error(pesan);
    }
    
    // 5. null secara jujur
    let mejaDipesan: number | null = null;
    mejaDipesan = 5;
    console.log(kategori, mejaDipesan); // → kuliner 5
    

    Sekarang perbandingan any dan unknown dengan data yang tidak jelas asalnya:

    // any-vs-unknown.ts
    const teksJson = '{"nama":"Sari","umur":25}';
    
    // Dengan any: tidak ada pemeriksaan, typo pun lolos
    const dataAny: any = JSON.parse(teksJson);
    console.log(dataAny.nmae); // → undefined (tidak ada yang memperingatkan)
    
    // Dengan unknown: dipaksa memeriksa dulu
    const dataUnknown: unknown = JSON.parse(teksJson);
    console.log(dataUnknown.nama); // ❌ error TS18046: 'dataUnknown' is of type 'unknown'.
    
    if (
      typeof dataUnknown === "object" &&
      dataUnknown !== null &&
      "nama" in dataUnknown &&
      typeof dataUnknown.nama === "string"
    ) {
      console.log(dataUnknown.nama.toUpperCase()); // → SARI
    }
    
    // catch (err) bertipe unknown di mode strict
    try {
      JSON.parse("{rusak");
    } catch (err) {
      const pesan = err instanceof Error ? err.message : String(err);
      console.log("Gagal parse:", pesan);
    }
    

    Pemeriksaan manual seperti di atas memang panjang. Kabar baiknya, di modul Data API kamu akan memakai Zod untuk melakukan pemeriksaan ini dalam satu baris.

    Kesalahan umum

    1. Menulis tipe berlebihan untuk hal yang sudah jelas. const total: number = 5 + 3 tidak salah, tapi berisik. Biarkan inferensi bekerja untuk variabel lokal; fokuskan anotasi di parameter dan batas data.
    2. Memakai String, Number, Boolean (kapital) sebagai tipe. Pakai huruf kecil: string, number, boolean.
    3. Memakai any untuk data dari luar. Pakai unknown lalu persempit atau validasi. any "menular": hasil operasi pada any juga any.
    4. Membuat array kosong tanpa tipe. const daftar = [] lalu diisi belakangan bisa membuat tipe yang tidak kamu inginkan. Tulis const daftar: string[] = [].
    5. Menyalahgunakan as. const user = data as User hanya membungkam compiler. Kalau data ternyata bukan User, bug tetap muncul di runtime.

    Latihan

    1. Mudah, Deklarasikan variabel untuk nama siswa, nilai ujian, dan status lulus tanpa menulis tipe. Arahkan kursor (hover) di editor untuk melihat tipe hasil inferensi. Lalu buat array nilaiKelas bertipe number[].
    2. Sedang, Buat tuple RGB berisi tiga angka dan function keHex(warna: RGB): string yang mengubahnya menjadi string seperti #ff8800.
    3. Menantang, Tulis function ambilAngka(input: unknown): number yang mengembalikan angka kalau input bertipe number, mengubah string berisi angka (misalnya "42") menjadi number, dan melempar error untuk kasus lain.
    Lihat solusi
    // 1. Mudah
    let namaSiswa = "Dewi";     // string
    let nilaiUjian = 88;        // number
    let lulus = nilaiUjian >= 75; // boolean
    const nilaiKelas: number[] = [88, 70, 95];
    console.log(namaSiswa, nilaiUjian, lulus, nilaiKelas.length); // → Dewi 88 true 3
    
    // 2. Sedang
    type RGB = [merah: number, hijau: number, biru: number];
    
    function keHex(warna: RGB): string {
      return "#" + warna.map((n) => n.toString(16).padStart(2, "0")).join("");
    }
    console.log(keHex([255, 136, 0])); // → #ff8800
    
    // 3. Menantang
    function ambilAngka(input: unknown): number {
      if (typeof input === "number") return input;
      if (typeof input === "string" && input.trim() !== "" && !Number.isNaN(Number(input))) {
        return Number(input);
      }
      throw new Error(`Bukan angka: ${String(input)}`);
    }
    console.log(ambilAngka(7));    // → 7
    console.log(ambilAngka("42")); // → 42
    // ambilAngka("abc") → melempar Error: Bukan angka: abc
    

    Ringkasan

    Video pendamping

    Kalau penjelasan di atas belum masuk, tonton ini. Video dari kanal YouTube pihak lain.

    Typescript Basic Types - Beginners LessonDave Gray · Bahasa InggrisBuka di YouTube

    Kuis pemahaman

    Pilih satu jawaban per soal. Penjelasan muncul setelah kamu menjawab.