Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

README.md

Modul 2 - Java Script & TypeScript

1. JavaScript Basics

JavaScript adalah bahasa pemrograman yang digunakan untuk menambahkan interaksi dan logika ke halaman web. Dalam modul ini, kalian akan mempelajari dasar-dasar JavaScript.

1.1. Menambahkan JavaScript ke HTML

  1. Inline JavaScript: Menggunakan atribut seperti onclick.

    <button onclick="alert('Hello World!')">Click Me</button>
  2. Internal JavaScript: Menambahkan di dalam tag <script>.

    <script>
    	function greet() {
    		alert("Hello, World!");
    	}
    </script>
  3. External JavaScript: Menghubungkan file eksternal.

    <script src="./script.js"></script>

1.2. Sintaks Dasar

  • Variabel: Menggunakan let, dan const. (kenapa nggada var mas?, karena rekom masa sekarang better let dan const yeah)

    let name = "Alice"; // variabel yang dapat diubah
    const age = 25; // variabel konstan

Permaslaahan Dengan Var

variabel yang dideklarasikan menggunakan var akan memiliki scope yang disebut sebagai function scope. Dalam javascript, hal ini berarti variabel tersbeut masih bisa diakses di luar blok (for, if) yang menyebabkan bug lebih susah dilacak.

Contoh:

if (true) {
  var name = "Kelinci";
}
console.log(name); // "Kelinci" -> masih bisa diakses

if (true) {
  let newName = "Alice";
}
console.log(newName); // ❌ Error: name is not defined
  • Tipe Data:

    • String
    • Number
    • Boolean
    • Null
    • Undefined
    • Object
    • Array
    let str = "Hello";
    let num = 10;
    let isTrue = true;
    let nothing = null;

1.3. Fungsi

  • Mendefinisikan Fungsi:

    function greet(name) {
    	return `Hello, ${name}!`;
    }
  • Fungsi Ekspresi:

    const greet = function (name) {
    	return `Hello, ${name}!`;
    };
  • Fungsi Panah:

    const greet = (name) => `Hello, ${name}!`;

1.4. Pengkondisian

  • If-Else:

    let score = 85;
    
    if (score > 90) {
    	console.log("Excellent");
    } else if (score > 70) {
    	console.log("Good");
    } else {
    	console.log("Needs Improvement");
    }

1.5. Looping

  • For Loop:

    for (let i = 0; i < 5; i++) {
    	console.log(i);
    }
  • While Loop:

    let count = 0;
    while (count < 5) {
    	console.log(count);
    	count++;
    }

1.6. Menggunakan Local Storage

Local Storage adalah penyimpanan di browser yang memungkinkan kalian menyimpan data secara permanen di sisi klien (hingga dihapus secara manual oleh pengguna).

1.6.1. Menyimpan Data ke Local Storage

Untuk menyimpan data ke local storage, gunakan metode localStorage.setItem(). Metode ini menerima dua parameter: kunci (key) dan nilai (value).

Contoh menyimpan data:

localStorage.setItem("username", "Alice");

const user = {
	name: "Alice",
	age: 25,
};
localStorage.setItem("user", JSON.stringify(user));

1.6.2. Mengambil Data dari Local Storage

Untuk mengambil data yang telah disimpan di local storage, gunakan metode localStorage.getItem(). Jika datanya adalah string yang di-encode sebagai JSON, gunakan JSON.parse() untuk mengubahnya kembali ke objek JavaScript.

Contoh mengambil data:

const username = localStorage.getItem("username");
console.log(username); // Output: Alice

const user = JSON.parse(localStorage.getItem("user"));
console.log(user.name); // Output: Alice

1.6.3. Menghapus Data dari Local Storage

Gunakan localStorage.removeItem() untuk menghapus item tertentu dari local storage.

Contoh menghapus data:

localStorage.removeItem("username");

removeItem tidak akan mengembalikan error apabila key yang dimasukkan tidak ditemukan

Untuk menghapus semua data yang tersimpan di local storage, gunakan localStorage.clear():

localStorage.clear();

2. Intermediate JavaScript

Setelah memahami dasar-dasar javascript, kalian akan melanjutkan ke konsep yang lebih kompleks.

2.1. Arrays

  • Mendefinisikan Array:

    let fruits = [🍏, 🍉, 🍊]; // menyimpan beberapa nilai (buah) dalam satu variabel
  • Manipulasi Array:

    fruits.push(🍇); // Menambah elemen di akhir array
    fruits.pop(); // Menghapus elemen terakhir
  • Menambah dan Menghapus Elemen di Awal Array:

    fruits.unshift(🍊); // Menambah elemen di awal array
    fruits.shift(); // Menghapus elemen pertama
  • Menggabungkan Dua Array:

    const moreFruits = [🍏, 🍉,];
    const allFruits = fruits.concat(moreFruits);
  • Mengakses Elemen dengan indexOf dan includes:

    const index = fruits.indexOf(🍏); // Mengembalikan index dari '🍏'
    const hasApple = fruits.includes(🍏); // Mengecek apakah array memiliki '🍏'
  • Menggunakan slice untuk Mengambil Subset:

    const someFruits = fruits.slice(1, 3); // Mengambil elemen dari index 1 hingga sebelum 3
  • Menggunakan splice untuk Menambah/Menghapus Elemen di Posisi Tertentu:

    fruits.splice(2, 0, 🍏); // Menambah 🍏 di index 2 tanpa menghapus elemen
    fruits.splice(1, 1); // Menghapus 1 elemen mulai dari index 1
  • Looping Melalui Array:

    fruits.forEach((fruit) => {
    	console.log(fruit);
    });

2.2. Objects

  • Mendefinisikan Objek:

    let person = {
    	name: "Alice",
    	age: 25,
    	greet: function () {
    		return `Hello, ${this.name}`;
    	},
    };
    let work = {
    	name: "Lorem Ipsum",
    	position: "Software Engineer",
    	greet: () => {
    		return `Hello, ${work.name}`;
    	},
    };
  • Akses Properti:

    console.log(person.name); // Mengakses dengan titik
    console.log(person["age"]); // Mengakses dengan bracket
    console.log(work.name); // Mengakses dengan titik
    console.log(work["position"]); // Mengakses dengan bracket
    console.log(work.greet()); // Mengakses dengan bracket

2.3. DOM Manipulation

2.3.1. DOM Document

document adalah objek utama yang mewakili seluruh halaman web. Klean bisa mengakses elemen, membuat elemen baru, dan melakukan manipulasi DOM lainnya menggunakan document.

Contoh mengakses elemen:

const title = document.getElementById("title");
const paragraphs = document.querySelectorAll("p");

2.3.2. DOM Elements

Elemen DOM bisa diakses dan dimanipulasi untuk mengubah konten, gaya, atribut, dll.

Contoh mengubah konten dan gaya:

title.textContent = "New Title";
title.style.color = "blue";

2.3.3. DOM HTML

innerHTML digunakan untuk mengubah atau menyisipkan konten HTML dalam elemen. (Awas kena XSS puhh)

Contoh:

const content = document.getElementById("content");
content.innerHTML =
	"<h1>Judul Baru</h1><p>Paragraf diubah dengan innerHTML.</p>";

2.3.4. DOM Forms

Untuk mengakses dan memanipulasi elemen form seperti input, textarea, dll., kalian bisa menggunakan properti value.

Contoh menangani form:

const form = document.getElementById("myForm");
form.addEventListener("submit", (event) => {
	event.preventDefault();
	const inputValue = document.getElementById("inputField").value;
	alert(`Input value: ${inputValue}`);
});

2.3.5. DOM CSS

Untuk mengubah gaya elemen, kalian bisa menggunakan properti style.

Contoh:

title.style.fontSize = "24px";
title.style.backgroundColor = "yellow";

2.3.6. DOM Animations

Klean bisa menambahkan animasi menggunakan CSS atau JavaScript. Dengan JavaScript, properti style bisa digunakan untuk mengubah transformasi dan transisi.

Contoh:

const box = document.getElementById("box");
box.style.transition = "transform 0.5s";
box.style.transform = "rotate(45deg)";

2.3.7. DOM Events

Event adalah tindakan yang dilakukan oleh pengguna atau browser seperti klik, scroll, dan input. Klean bisa menggunakan event seperti click, input, atau submit.

Contoh event click yang digunakan di HTML nantinya:

function changeText(id) {
	id.innerHTML = "Huft!";
}

2.3.8. DOM Event Listener

addEventListener digunakan untuk menambahkan event listener ke elemen DOM.

Contoh menangani klik tombol:

button.addEventListener("click", () => {
	console.log("Button was clicked!");
});

2.3.9. DOM Nodes

Semua elemen di DOM adalah node, dan kalian bisa memanipulasinya dengan metode seperti appendChild, removeChild, atau replaceChild.

Contoh menghapus elemen:

const parentElement = document.getElementById("parent");
const childElement = document.getElementById("child");
parentElement.removeChild(childElement);

2.3.10. DOM Collections & Node List

HTMLCollection dan NodeList adalah koleksi elemen DOM. Klean bisa melakukan iterasi di atas koleksi tersebut seperti pada array, meskipun tidak sepenuhnya sama.

Contoh dengan NodeList:

const paragraphs = document.querySelectorAll("p");
paragraphs.forEach((p) => {
	p.style.color = "green";
});

Contoh dengan HTMLCollection:

const divs = document.getElementsByTagName("div");
for (let i = 0; i < divs.length; i++) {
	divs[i].style.backgroundColor = "yellow";
}

3. Advanced JavaScript

Di bagian ini, kalian akan mempelajari fitur dan konsep lanjutan dalam JavaScript.

3.1. Asynchronous JavaScript

  • Promises:

    const fetchData = new Promise((resolve, reject) => {
    	setTimeout(() => {
    		const data = { name: "Alice" };
    		resolve(data);
    	}, 2000);
    });
    
    fetchData.then((data) => console.log(data));
  • Async/Await:

    async function fetchData() {
    	const response = await fetch("https://api.example.com/data");
    	const data = await response.json();
    	console.log(data);
    }
    
    fetchData();
  • Callback:

    function fetchData(callback) {
    	setTimeout(() => {
    		const data = {
    			name: "Alice",
    			age: 24,
    			posistion: "Software Engineer",
    		};
    		callback(data);
    	}, 2000);
    }
    
    function handleData(data) {
    	console.log(data);
    }
    
    fetchData(handleData);

Fungsi fetchData menerima fungsi callback (handleData) sebagai argumen, yang kemudian dipanggil setelah setTimeout selesai dan data siap digunakan.

3.2. Error Handling

  • Try-Catch:

    try {
    	// kode yang mungkin terjadi error
    } catch (error) {
    	console.error("Error occurred:", error);
    }

3.3. Closures

  • Contoh Closures:

    function pesanKamuKeDia() {
    	const chatKamu = "Kamu dah tidur belum";
    	return function pesanYangDiaSukai() {
    		const chatYangDiaSukai = "Haii, sudah makan belum?";
    		console.log({ chatYangDiaBaca: chatYangDiaSukai });
    	};
    }
    
    const hasil = pesanKamuKeDia();
    hasil(); // Output: "Haii, sudah makan belum?"

4. Expert JavaScript

Pada level ini, kalian akan diberikan topik-topik lanjutan dan praktik JavaScript.

4.1. Functional Programming

  • Higher-Order Functions:

    const add = (a) => (b) => a + b;
    const add5 = add(5);
    console.log(add5(10)); // Output: 15
  • Map, Filter, Reduce:

    const numbers = [1, 2, 3, 4, 5];
    const doubled = numbers.map((num) => num * 2);                // [2, 4, 6, 8, 10]
    const evenNumbers = numbers.filter((num) => num % 2 === 0);   // [2, 4]
    const sum = numbers.reduce((acc, num) => acc + num, 0);       // 1 + 2 + 3 + 4 + 5 = 15

4.2. Event Delegation

  • Menggunakan Event Delegation:

    document.querySelector("#parent").addEventListener("click", (event) => {
    	if (event.target.matches("button")) {
    		console.log("Button clicked:", event.target.textContent);
    	}
    });

4.3. Best Practices

  • Gunakan let dan const daripada var untuk mendeklarasikan variabel
  • Tulis kode yang bersih dan terorganisir dengan mengikuti prinsip KISS
  • Gunakan linting tools seperti ESLint untuk menjaga konsistensi kode

5. Typescript & NodeJS

Typescript NodeJS

5.1 Apa itu TypeScript🤔???

TypeScript adalah sebuah bahasa pemrograman yang dikembangkan di atas JavaScript. Dibandingkan dengan JavaScript, TypeScript menyediakan fitur tambahan yang mempermudah pengembangan aplikasi berskala besar.

TypeScript adalah superset dari JavaScript, yang berarti semua kode JavaScript yang valid juga valid di TypeScript. Namun, TypeScript menambahkan syntax tambahan seperti tipe data (type) dan antarmuka (interface) untuk memberikan lebih banyak struktur pada kode.

Proses Transpilasi kode yang ditulis dalam TypeScript tidak dijalankan langsung di browser atau Node.js. Kode ini perlu dikonversi menjadi JavaScript terlebih dahulu melalui proses yang disebut transpiling. Setelah dikonversi, hasilnya adalah kode JavaScript biasa yang dapat dijalankan di:

  • Browser: Untuk membuat aplikasi web.

  • Node.js atau Deno: Untuk membuat aplikasi server atau utilitas lain berbasis JavaScript.

5.2 Mengapa Typescript😣???

  • Integrasi IDE

    TypeScript dirancang untuk bekerja lebih baik dengan Code Editor seperti VS Code, sehingga memudahkan dalam penulisan dan perbaikan kode.

  • Error Checking

    Salah satu keuntungan utama TypeScript adalah kemampuannya untuk menangkap kesalahan langsung saat penulisan kode, sehingga bug dapat diperbaiki sebelum program dijalankan.

  • Scalable

    TypeScript sangat berguna dalam proyek berskala besar karena adanya tipe data yang lebih jelas, sehingga memudahkan pengembang dalam memahami dan menjaga kualitas kode.

Javascript😁 vs Typescript😎

Fitur TypeScript JavaScript
Tipe Data Menyediakan tipe statis Bertipe dinamis
Perkakas Dilengkapi dengan IDE dan editor kode Tools bawaan terbatas
Sintaks Mirip dengan JavaScript, dengan fitur tambahan Syntax Standar JavaScript standar
Kompatibilitas Kompatibel dengan JavaScript Tidak dapat menjalankan TypeScript di file JavaScript
Debugging Penulisan kode yang lebih kuat/strict dapat membantu mengidentifikasi kesalahan Memerlukan lebih banyak debugging dan pengujian
Tingkat Kesulitan Membutuhkan waktu untuk mempelajari fitur tambahan Sintaks JavaScript standar lebih familier
Tipe Bahasa Object-oriented Prototype-based language

5.3 Cara Menginstal NodeJS

  • Download prebuilt-installer NodeJS (gunakan versi yang memiliki label LTS) pada link berikut. Nantinya akan muncul tampilan seperti di bawah ini image

  • Install nodeJS melalui prebuilt-installer yang sudah kalian unduh.

  • Package Manager NPM juga akan terinstal.

  • untuk memeriksa apakah NodeJS dan NPM telah terpasang, gunakan command berikut pada terminal:

    • Cek versi NodeJS
    node -v
    • Cek versi NPM
    npm -v
image

5.4 Memulai Proyek 'TypeScript' Pertama🚀

- Persiapan Proyek

Pertama, siapkan folder proyek dan install TypeScript sebagai dependency pengembangan. Buka terminal dan jalankan perintah berikut satu per satu:

# Membuat dan masuk ke folder proyek
mkdir proyek-ts
cd proyek-ts

# Membuat file package.json secara otomatis
npm init -y

# Menginstal TypeScript untuk proyek ini
npm install typescript --save-dev

- Menulis Kode

Selanjutnya, kita akan menulis kode TypeScript.

  • Buat folder baru bernama src.
  • Di dalam src, buat file baru bernama index.ts.
  • Isi file src/index.ts dengan kode berikut:
function sapa(nama: string) {
  console.log(`Halo, ${nama}!`);
}

sapa("Praktikan");

- Kompilasi & Eksekusi

Terakhir, kita ubah kode TypeScript (.ts) menjadi JavaScript (.js) lalu jalankan.

  • Jalankan perintah ini di terminal untuk mengompilasi file src/index.ts.
npx tsc src/index.ts

Perintah ini akan membuat file baru bernama index.js di dalam folder src.

  • Jalankan Program Eksekusi file JavaScript hasil kompilasi untuk melihat outputnya.
node src/index.js

Output yang Diharapkan:

Halo, Praktikan!

Selamat! Anda telah berhasil menjalankan program TypeScript pertama Anda.

5.5 Type Annotation di Typescript

Type annotation merupakan cara kita untuk memberitahu Typescript mengenai tipe data dari sebuah variabel, parameter fungsi, serta nilai yang di return oleh sebuah fungsi.

Primitive Types (string, number, dan boolean)

Adalah tipe data yang paling dasar dan umum digunakan untuk menyimpan teks, angka, dan nilai boolean yaitu true atau false.

// Variabel ini HANYA boleh berisi teks (string)
let text: string = 'Hello World!'

// Variabel ini HANYA boleh berisi angka (number)
let num: number = 58.0

// Variabel ini HANYA boleh berisi nilai benar atau salah (boolean)
let isTrue: boolean = false

Arrays

Untuk mendefinisikan sebuah array, kita dapat menyisipkan [] setelah nama tipenya.

// Variabel ini HANYA boleh berisi kumpulan teks (string)
let colorArray: string[] = ["Red", "Green", "Blue"]

// Variabel ini HANYA boleh berisi kumpulan angka (number)
let numberArray: number[] = [1, 3, 5, 6, 9]

// Variabel ini HANYA boleh berisi kumpulan boolean
let booleanArray: boolean[] = [true, false, true, false]

Any

Dengan menggunakan any, nantinya sebuah variabel dapat diisi dengan tipe data apapun dan dapat dioperasikan sesuai preferensi kita.

⚠️ Gunakan tipe data ini dengan hati-hati, karena penggunannya akan menghilangkan pengecekan tipe data pada variabel yang merupakan fitur utama dari Typescript.

// 'obj' bisa diisi dan diubah menjadi apa saja tanpa error
let obj: any = { count: 0 };

obj.foo();
obj();
obj.bar = 100;
obj = "hello";

Function

Type annotation dalam sebuah function digunakan untuk mendeklarasikan tipe data untuk parameter atau input dari sebuah tersebut serta nilai yang di return oleh sebuah fungsi.

Parameter Type Annotation

// Fungsi ini hanya menerima parameter 'name' yang bertipe string
function greet(name: string) {
	console.log(`Hello ${name.toUpperCase()}! How are you?`)
}

greet("John Doe"); // Benar
// greet(123); // Akan menjadi error karena 123 bukan string

Return Type Annotation

// Fungsi ini PASTI akan selalu me-return nilai boolean
function isNight(): boolean {
	return true
}

Object

Untuk objek, type annotation dapat dilakukan dengan mendefinisikan "bentuk" atau struktur objeknya dengan mendefinisikan properti apa saja yang ada di dalamnya beserta tipe datanya.

Variable Annotation

// Variabel user dengan properti 'name' (string) dan 'age' (number)
const user: { name: string, age: number } = {
	name: "John Doe",
	age: 25
}

Function Annotation

// Fungsi ini hanya menerima objek dengan struktur { lat: number, lng: number }
function showCoord(coord: { lat: number, lng: number }) {
	console.log("Latitude: ": coord.lat)
	console.log("Latitude: ": coord.lng)
} 

showCoord({ lat: 37.272011, lng: -115.815498 })

Optional Properties

Terkadang, sebuah properti dalam objek tidak wajib ada. Untuk itu, kita dapat menandainya sebagai properti yang opsional dengan menambahkan ? (tanda tanya) setelah nama properti.

// Properti 'last' tidak wajib diisi karena ada tanda '?'
function showFullName(user: { first: string, last?: string }) {
	// Karena 'last' opsional, bisa jadi nilainya undefined
	console.log(`Full name: ${user.first} ${user.last}`)
}

showFullName({ first: "John" })
showFullName({ first: "John", last: "Doe" })

5.6 Fitur Lain di Typescript

Union

Memungkinkan sebuah variabel atau parameter untuk dapat memiliki lebih dari satu kemungkinan tipe data. Untuk mendeklarasikan union type, kita dapat menggunakan tanda | untuk memisahkan tipe data yang digunakan.

function showUserId(id: string | number) {
	console.log("User ID: ", id)
}

showUserId("ff1a33c0-e73c-4f45-a894-42ee86115a12")
showUserId(482)

Penanganan Union Types

Masalah umum yang terjadi dalam penggunaan union types adalah ketika ingin menggunakan methods spesifik dari salah satu tipe data yang digunakan. Berikut contoh kodenya:

function showUserId(id: string | number) {
	console.log("User ID: ", id.toUpperCase())
}

showUserId(482)

Kode tersebut akan menghasilkan error:

Property 'toUpperCase' does not exist on type 'string | number'.
	Property 'toUpperCase' does not exist on type 'number'.

Error tersebut terjadi karena method toUpperCase() tidak terdapat pada tipe data number. yang mana dalam case tersebut, compiler tidak mengetahui apakah id bertipe string atau number. Untuk itu, kita dapat melakukan type checking terlebih dahulu sebelum menggunakan sebuah method seperti pada kode berikut:

function showUserId(id: string | number) {
	if (typeof id === "string") {
		console.log("User ID: ", id.toUpperCase())
	} else {
		console.log("User ID: ", id)
	}
}

showUserId(482)

Contoh lain misalnya untuk menangani parameter dengan tipe string dan array string dapat dilihat pada kode berikut:

function welcomePeople(value: string[] | string) {
	if (Array.isArray(value)) {
		// Disini, "value" bertipe string array (string[])
		console.log("Hello, " + x.join(" and "));
	} else {
		// Disini, "value" bertipe string
		console.log("Welcome lone traveler " + x);
	}
}

Type Alias

Merupakan cara kita untuk memberi sebuah nama panggilan pada sebuah tipe data, terutama untuk tipe data yang kompleks seperti objek. Tujuannya adalah agar kode lebih mudah dibaca dan dapat digunakan kembali (reusable).

type Location = {
	name: string
	address: string
	coordinate: {
		lat: number
		lng: number
	}
}

function showAddress(loc: Location) {
	console.log("Name: ", loc.name)
	console.log("Address: ", loc.address)
	console.log("Coordinate: ", loc.coordinate)
}

showAddress({ name: "Gedung X", address: "Jl. Patimura No. 15", coordinate: { lat: 37.272011, lng: -115.815498 }})

Interfaces

Merupakan cara lain untuk mendefinisikan bentuk atau blueprint dari suatu objek. Fungsinya sangat mirip dengan type alias akan tetapi dengan beberapa perbedaan.

interface Product {
    name: string;
    price: number;
    isAvailable: boolean;
}

function showProduct(product: Product) {
    console.log(`Produk: ${product.name}, Harga: Rp${product.price}`);
}

showProduct({ name: "Buku TypeScript", price: 150000, isAvailable: true });

Perbedaan Interface dan Type Alias

Meskipun secara deklarasi dan penggunaan terlihat sama, keduanya mempunyai beberapa perbedaan:

  • Extending: interface bisa di extend oleh interface lain, seperti konsep inheritance atau pewarisan dalam OOP. type alias sebenarnya dapat melakukan hal yang serupa dengan intersection &, akan tetapi untuk keperluan extend, interface lebih baik dari segi syntaks. Berikut adalah contoh dari konsep extending:

     interface BaseObject {
     	name: string
     	address: string
     }
    
     interface ExtendedObject extends BaseObject {
     	type: "HOME" | "OFFICE"
     }
    
     // VS
    
     type BaseObject = {
     	name: string
     	address: string
     }
    
     type ExtendedObject = BaseObject & {
     	type: "HOME" | "OFFICE"
     }
  • Declaration Merging: Ketika kita mendefinisikan interface dengan nama yang sama lebih dari sekali, Typescript akan menggabungkannya menjadi satu. Sementara itu, type alias tidak bisa melakukan hal ini. Berikut adalah contoh dari konsep declaration merging:

     interface Room {
     	name: string
     	num: number
     }
     
     interface Room {
     	floor: number
     }
     
     // Pada akhirnya, Room akan menjadi:
     interface Room {
     	name: string
     	num: number
     	floor: number
     }

Type Assertions

Type assertions* bukanlah sebuah tipe data, melainkan hanya sebuah petunjuk untuk Typescript agar memperlakukan sebuah value sebagai tipe yang berbeda. Hal ini berguna ketika Typescript tidak memiliki cukup informasi untuk mengetahui tipe data yang sebenarnya, contohnya saat mengambil elemen dari DOM.

// TypeScript hanya tahu ini adalah HTMLElement secara umum
const myCanvas = document.getElementById("main_canvas");

// Kita tahu ini adalah elemen canvas, jadi kita beri tahu TypeScript
const myCanvasAsserted = document.getElementById("main_canvas") as HTMLCanvasElement;
// Sekarang kita bisa mengakses properti spesifik canvas seperti .getContext() tanpa error

// Ada juga sintaks lain (kurung sudut), tapi 'as' lebih umum digunakan
const myCanvasAsserted2 = <HTMLCanvasElement>document.getElementById("main_canvas");

⚠️ Penggunaan type assertions akan menonaktifkan pemeriksaan tipe. Jika salah memberikan tipe, misalnya elemen tersebut sebenarnya bukan canvas, maka kode akan error saat dijalankan di browser, bukan saat proses compile .

Literal Types

Memungkinkan kita untuk mendefinisikan tipe yang hanya bisa berisi satu nilai spesifik.

let responseStatus: "success";

responseStatus = "success"; // OK
// responseStatus = "error"; // Akan terjadi error karena tipe 'string' "error" tidak bisa diassign ke tipe '"success"'.

Literal types sendiri umumnya digunakan bersama dengan union types:

// Variabel ini hanya boleh berisi salah satu dari tiga string spesifik ini
let trafficLight: "red" | "yellow" | "green";

trafficLight = "yellow"; // OK
trafficLight = "red"; // OK
// trafficLight = "blue"; // Akan terjadi error

Penggunaan literal types sangat berguna untuk mencegah kesalahan pengetikan dan membatasi value yang mungkin digunakan untuk sebuah variabel.

null dan undefined

Dalam Typescript, null (tidak ada nilai) dan undefined (variabel belum diinisialisasi) menjadi tipe data tersendiri. Secara default, proyek Typescript modern cukup strict dengan tipe null dan undefined.

let nama: string = "Budi";
// nama = null; // Error! Tipe 'null' tidak bisa diassign ke tipe 'string'.

// Jika sebuah variabel memang bisa bernilai null, tipe 'null' harus didefinisikan
let namaOrNull: string | null = "Andi";
namaOrNull = null; // OK

Enums

Merupakan cara untuk mendefinisikan sekumpulan nilai constant. Penggunaan enum bermanfaat untuk mencegah string yang salah ketik.

Numeric Enums

Secara default, enum akan memberikan nilai angka yang dimulai dari 0.

enum Direction {
    Up,    // bernilai 0
    Down,  // bernilai 1
    Left,  // bernilai 2
    Right  // bernilai 3
}

let playerDirection: Direction = Direction.Up;

if (playerDirection === Direction.Up) {
	// Lebih mudah dibaca daripada if (playerDirection === 0)
    console.log("Pemain bergerak ke atas!");
}

String Enums

Untuk mempermudah proses debugging, kita dapat menggunakan string enum.

enum HttpStatus {
    OK = "OK",
    NotFound = "NOT_FOUND",
    InternalServerError = "INTERNAL_SERVER_ERROR",
}

function handleResponse(status: HttpStatus) {
    if (status === HttpStatus.OK) {
        console.log("Respons berhasil!");
    } else if (status === HttpStatus.NotFound) {
        console.log("Data tidak ditemukan.");
    }
}

handleResponse(HttpStatus.OK);

5.7 Contoh Website Sederhana dengan TypeScript

Kalian bisa lihat contoh project sederhana menggunakan TypeScript pada website berikut: TypeScript Calculator Website

Sebagai referensi, kalian bisa lihat source codenya pada repository berikut: TypeScript Calculator Repository

Di situ kalian juga bisa melihat perbedaan penggunaan type safety pada TypeScript dibandingkan dengan JavaScript biasa. Berikut adalah website JavaScript: JavaScript Calculator Website

5.8 Best Practice TypeScript

Pengaplikasian TypeScript sangat membantu dalam pengerjaan proyek, terutama yang berskala besar. Namun apabila diterapkan dengan ala kadarnya, dapat membuat setiap orang yang bekerja dalam proyek tersebut kebingungan.

ts-any-meme

TypeScript bertujuan untuk mempermudah developer dalam mengembangkan aplikasi JavaScript, bukan memperumit.

Untuk itu, kalian bisa manfaatkan sedikit contoh best practice di bawah ini agar aplikasi kalian mudah dipahami oleh orang lain.

  1. Definisikan type di file terpisah

Mencampurkan terlalu banyak Type atau Interface dalam satu file, terlebih pada file yang sama dengan function dapat membuat file lebih susah dirawat (maintain).

no-import

Butuh 20 baris hanya untuk mendefinisikan interface yang akan digunakan, boros baris :(

Akan lebih baik apabila Type dan Interface diletakkan pada sebuah folder khusus yang berisi semua definisi tipe.

Contoh Struktur Folder:

my_ts/
 ┃
 ┣ interfaces/            // Folder Interfaces
 ┃ ┗ animal.interface.ts
 ┃ ┗ post.interface.ts
 ┃ ┗ user.interface.ts
 ┃
 ┗ tes-bentar.ts          // File Function

folder-no-index

Impor semua yang akan digunakan pada masing - masing file .interface

animal.interface.ts

export interface Animal {
  species: string;
  legs: number;
  can_fly: boolean;
  can_swim: boolean;
}

post.interface.ts

export interface Post {
  creator: string;
  title: string;
  description: string;
  total_click: number;
}

user.interface.ts

export interface User {
  name: string;
  age: number;
  address: string;
  is_old: boolean;
}

Hasil Akhir:

Pada akhirnya kalian akan mendapat seperti ini pada file function kalian,

import-1

Perbandingan

import-comparison

  1. Terlalu banyak yang diimpor? Gunakan index.ts

Dari contoh sebelumnya, terlihat bahwa kita masih harus mengimpor setiap file satu persatu. Untuk memudahkan impor, kita bisa menambahkan file index.ts pada folder interfaces.

folder-with-index

index.ts

export * from './animal.interface';
export * from './post.interface';
export * from './user.interface';

Hasil Akhir

import-2

  1. Manfaatkan Type Manupulation

TypeScript menyediakan berbagai utility types yang dapat membantu developer dalam menulis kode yang fleksibel dan tidak repetitif

  1. Generics

Generics memungkinkan kita membuat Tipe Dinamis untuk digunakan dalam kasus yang bervariasi.

function identity<T>(value: T): T {
return value;
}

const str = identity<string>("Hello"); // str: string
const num = identity(123);             // num: number (infer otomatis)
  1. Partial

Partial<T> berarti seluruh properti pada tipedata T akan diubah menjadi opsional

interface User {
id: number;
name: string;
email: string;
}

// Apabila terdapat variabel dengan tipedata partial dari User

type KindaUser = Partial<User>;

// Maka tipedatanya sama saja seperti:

interface KindaUser {
id?: number;
name?: string;
email?: string;
}

Contoh Lain:

interface User {
id: number;
name: string;
email: string;
}

function updateUser(id: number, data: Partial<User>) {
// data bisa hanya berisi sebagian field
}

updateUser(1, { name: "New Name" }); // Tidak perlu memasukkan id dan email
  1. Pick

Pick<T, K> membuat tipe baru hanya dengan memilih beberapa properti dari tipe asal.

interface User {
id: number;
name: string;
email: string;
password: string;
}

type UserProfile = Pick<User, "id" | "name" | "email">;

const profile: UserProfile = {
id: 1,
name: "Jone",
email: "jone@doe.com",
};
  1. Omit

Omit<T, K> adalah kebalikan dari Pick, Omit akan membuat tipe baru dengan menghapus properti tertentu.

type UserWithoutPassword = Omit<User, "password">;

const user: UserWithoutPassword = {
id: 1,
name: "Alibaba",
email: "ali@baba.com",
};

Dokumentasi lengkap terkait dengan Type Manipulation terdapat pada situs resmi TypeScript. Klik untuk Akses

Happy Coding!