Pemrograman · Bahasa pemrograman
Tutorial TypeScript untuk pemula
Jawaban singkat
TypeScript adalah JavaScript dengan tipe statis. Anda menambahkan anotasi tipe seperti let count: number = 0, dan compiler tsc memeriksanya sebelum mengubah kode menjadi JavaScript biasa yang berjalan di browser mana pun atau di Node.js. Konsep utamanya: tipe dasar, interface dan type alias untuk bentuk objek, union type dengan narrowing, serta generic untuk kode yang dapat dipakai ulang. Tipe dihapus saat runtime.
Apa itu TypeScript dan untuk apa dipakai
TypeScript adalah bahasa open source yang dikembangkan Microsoft dan pertama kali dirilis pada 2012. Setiap program JavaScript yang valid juga valid sebagai TypeScript, jadi Anda bisa mengadopsinya file demi file. Type checker menangkap kesalahan seperti properti yang salah ketik atau pemeriksaan null yang terlewat saat Anda mengetik, dan editor memakai tipe untuk autocomplete serta rename yang aman. TypeScript banyak dipakai untuk aplikasi front-end besar (Angular ditulis dengannya, dan React, Vue, serta Svelte mendukungnya dengan baik), back end Node.js, dan pustaka.
Instal dan jalankan Hello, world
Instal Node.js terlebih dahulu, lalu instal compiler di proyek Anda dengan npm. tsc mengompilasi file .ts menjadi .js.
const message: string = "Hello, world";
console.log(message);npm install --save-dev typescript
npx tsc --init # creates tsconfig.json
npx tsc hello.ts # writes hello.js
node hello.js
# Hello, worldVersi terbaru Node.js, Deno, dan Bun juga dapat menjalankan file .ts secara langsung dengan membuang anotasi tipe. Mereka tidak melakukan type-check, jadi tetap jalankan npx tsc --noEmit untuk menemukan error tipe.
Tipe dasar dan type inference
Anda jarang perlu menulis setiap tipe. Saat menginisialisasi variabel, TypeScript menyimpulkan tipenya: let n = 5 bertipe number. Beri anotasi pada parameter fungsi dan API publik.
| Tipe | Contoh | Catatan |
|---|---|---|
number | let n: number = 3.5 | Bilangan bulat dan desimal |
string | let s: string = "hi" | Teks |
boolean | let ok: boolean = true | true atau false |
| Array | number[] atau Array<number> | Kedua bentuk bermakna sama |
| Tuple | [string, number] | Panjang dan posisi tetap |
unknown | let x: unknown | Nilai apa pun, harus diperiksa sebelum dipakai |
any | let y: any | Mematikan pemeriksaan; hindari |
void / never | tipe kembalian fungsi | Tidak mengembalikan apa pun / tidak pernah kembali |
let count = 0; // inferred as number
count = "ten"; // error: Type 'string' is not assignable to type 'number'
const names: string[] = ["Ann", "Bo"];
const pair: [string, number] = ["age", 31];Baris kedua sengaja berupa error kompilasi, ditampilkan untuk memperlihatkan apa yang dilaporkan checker.
Fungsi, alur kontrol, dan narrowing
Alur kontrol (if, for, while, switch) persis sama seperti di JavaScript. Yang ditambahkan TypeScript adalah narrowing: setelah pemeriksaan seperti typeof x === "string", compiler tahu tipe yang lebih spesifik di dalam cabang tersebut.
function greet(name: string, greeting = "Hello"): string {
return `${greeting}, ${name}!`;
}
function formatId(id: string | number): string {
if (typeof id === "number") {
return id.toFixed(0).padStart(6, "0"); // id is number here
}
return id.toUpperCase(); // id is string here
}
console.log(greet("Lin")); // Hello, Lin!
console.log(formatId(42)); // 000042
console.log(formatId("ab7")); // AB7string | number adalah union type: nilainya salah satu dari tipe yang tercantum. Parameter opsional ditulis name?: string, dan tipenya mencakup undefined.
Interface dan type alias
Deskripsikan bentuk objek dengan interface atau type alias type. TypeScript memeriksa struktur, bukan nama: objek apa pun dengan properti yang tepat dianggap cocok.
interface User {
id: number;
name: string;
email?: string; // optional
readonly createdAt: Date;
}
type Role = "admin" | "editor" | "viewer"; // string literal union
function describe(user: User, role: Role): string {
const contact = user.email ?? "no email";
return `${user.name} (${role}, ${contact})`;
}
const ann: User = { id: 1, name: "Ann", createdAt: new Date() };
console.log(describe(ann, "editor")); // Ann (editor, no email)Fitur khas: generic dan discriminated union
Generic memungkinkan satu fungsi atau tipe bekerja dengan banyak tipe sambil menjaga keterkaitannya. Discriminated union adalah union dari tipe objek yang memiliki field literal yang sama, sehingga switch pada field itu mempersempit tipe, dan compiler bisa memeriksa bahwa setiap kasus sudah ditangani.
function first<T>(items: T[]): T | undefined {
return items[0];
}
const n = first([10, 20]); // n: number | undefined
const s = first(["a", "b"]); // s: string | undefined
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rect"; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "rect":
return shape.width * shape.height;
}
}
console.log(n, s, area({ kind: "rect", width: 2, height: 3 })); // 10 a 6Utility type bawaan membuat tipe baru dari tipe lama: Partial<User> membuat setiap properti opsional, Pick<User, "id" | "name"> hanya mempertahankan sebagian properti, dan Record<string, number> mendeskripsikan dictionary.
Penanganan error
Error bekerja seperti di JavaScript, dengan throw dan try/catch. Dengan opsi strict aktif, nilai yang tertangkap bertipe unknown, karena nilai apa pun bisa dilempar, jadi periksa dahulu sebelum dipakai.
function parseAge(text: string): number {
const age = Number(text);
if (!Number.isInteger(age) || age < 0) {
throw new Error(`invalid age: ${text}`);
}
return age;
}
try {
parseAge("abc");
} catch (err: unknown) {
const message = err instanceof Error ? err.message : String(err);
console.log(message); // invalid age: abc
}Program kecil yang lengkap: inventaris bertipe
interface Item {
name: string;
price: number;
qty: number;
}
type Summary = { total: number; cheapest?: Item; outOfStock: string[] };
function summarize(items: Item[]): Summary {
let total = 0;
let cheapest: Item | undefined;
const outOfStock: string[] = [];
for (const item of items) {
total += item.price * item.qty;
if (item.qty === 0) outOfStock.push(item.name);
if (!cheapest || item.price < cheapest.price) cheapest = item;
}
return { total, cheapest, outOfStock };
}
const result = summarize([
{ name: "pen", price: 1.5, qty: 10 },
{ name: "book", price: 12, qty: 2 },
{ name: "bag", price: 30, qty: 0 },
]);
console.log(result.total, result.cheapest?.name, result.outOfStock);
// 39 pen [ 'bag' ]Coba ubah qty: 10 menjadi qty: "10": compiler melaporkan error sebelum kode dijalankan.
Kesalahan umum pemula
- Memakai
anyuntuk membungkam error. Pilihunknownlalu persempit. - Terlalu sering memakai type assertion
as, yang menyuruh compiler percaya pada Anda alih-alih memeriksa. - Membiarkan
strictmati ditsconfig.json. Aktifkan di proyek baru; opsi ini mengaktifkan pemeriksaannull. - Menulis tipe yang sebenarnya sudah bisa disimpulkan compiler, sehingga menambah kebisingan tanpa keamanan.
Langkah selanjutnya
Baca TypeScript Handbook resmi, dan bereksperimenlah di TypeScript Playground di typescriptlang.org, yang menampilkan JavaScript hasil kompilasi dan error secara berdampingan. Lalu pelajari opsi tsconfig.json, file deklarasi tipe untuk pustaka (paket @types/...), dan TypeScript dengan framework pilihan Anda.
FAQ
Apakah TypeScript bahasa yang berbeda dari JavaScript?
TypeScript adalah superset JavaScript: ia menambahkan sintaks tipe dan sebuah checker, lalu dikompilasi menjadi JavaScript biasa. Perilaku runtime-nya sama dengan JavaScript yang dihasilkan.
Perlukah belajar JavaScript sebelum TypeScript?
Pelajari dasar JavaScript dulu (variabel, fungsi, objek, promise), karena TypeScript tidak mengubahnya. Setelah itu tambahkan TypeScript; tipe lebih mudah dipelajari jika perilaku runtime sudah dikenal.
Apa perbedaan interface dan type?
Keduanya mendeskripsikan bentuk objek. Interface dapat diperluas dan digabung dengan mendeklarasikannya lagi; type alias juga dapat menamai union, tuple, dan tipe non-objek lain. Untuk bentuk objek biasa, keduanya cocok.
Apakah TypeScript membuat kode saya lebih cepat?
Tidak. Tipe dihapus saat kompilasi, sehingga hasilnya berjalan secepat JavaScript yang ditulis tangan. Manfaatnya adalah bug lebih sedikit dan tooling lebih baik.