Fungsi TypeScript adalah fungsi JavaScript dengan tipe pada parameternya dan, kalau mau, pada nilai kembaliannya. Setiap parameter mendapat anotasi, tipe kembalian ditulis setelah daftar parameter, dan compiler memeriksa setiap pemanggilan terhadap keduanya.
Kedua pemanggilan yang salah itu adalah error saat kompilasi (TS2345 dan TS2554). Komentar // @ts-expect-error memberi tahu compiler bahwa baris berikutnya memang diharapkan error, jadi sisa file tetap berjalan. Hapus salah satunya lalu jalankan lagi untuk melihat pesan error yang sebenarnya.
Tipe Parameter
Setiap parameter ditulis name: Type. Dengan strict, yang aktif secara default di TypeScript 7, parameter tanpa anotasi dan tanpa konteks untuk disimpulkan adalah error: Parameter 'x' implicitly has an 'any' type. (TS7006). Jadi dalam praktiknya, setiap parameter fungsi yang berdiri sendiri diberi anotasi.
Tipe apa pun bisa dipakai sebagai tipe parameter: tipe primitif, array, tipe object, union, bahkan fungsi lain.
TypeScript juga memeriksa jumlah argumen. Mengirim argumen lebih banyak atau lebih sedikit daripada yang dideklarasikan fungsi adalah error, berbeda dengan JavaScript biasa yang mengisi argumen yang kurang dengan undefined dan mengabaikan kelebihannya. Untuk membuat parameter opsional atau memberinya nilai default, lihat parameter opsional.
Tipe Kembalian: Dianotasi atau Disimpulkan
Tipe kembalian ditulis setelah tanda kurung tutup: function f(): Type. Sifatnya opsional. Tanpa anotasi, TypeScript menyimpulkan tipenya dari setiap return di dalam body fungsi.
Anotasi layak ditulis kalau fungsinya di-export, punya beberapa jalur return, atau rekursif. Error-nya lalu muncul di dalam fungsi, tepat di return yang salah, bukan di pemanggil. Contoh klasiknya adalah percabangan yang lupa mengembalikan nilai:
Compiler melaporkan index.ts(2,32): error TS2366: Function lacks ending return statement and return type does not include 'undefined'. Tambahkan return "C"; di akhir dan kodenya berjalan. Tanpa anotasi : string, fungsi itu akan lolos kompilasi dengan tipe hasil inferensi "A" | "B" | undefined, dan masalahnya pindah ke siapa pun yang memakai hasilnya.
void: Fungsi yang Tidak Mengembalikan Apa Pun
Fungsi yang hanya melakukan sesuatu (mencetak log, menulis, mengubah data) bertipe kembalian void. Itulah yang disimpulkan TypeScript kalau tidak ada return dengan nilai, dan kamu juga bisa menuliskannya secara eksplisit.
Aturan tentang void berikut sering mengejutkan:
| Situasi | Boleh? |
|---|---|
function f(): void { return 42; } | Tidak: Type 'number' is not assignable to type 'void'. (TS2322) |
const f: () => void = () => 42; | Ya: nilainya dikembalikan, tetapi pemanggil tidak boleh mengandalkannya |
function f(): undefined {} | Ya (TypeScript 5.1 ke atas) |
Memakai hasil fungsi void di dalam if | Tidak: An expression of type 'void' cannot be tested for truthiness. (TS1345) |
Baris kedua memang disengaja. Karena itulah arr.forEach(x => list.push(x)) lolos kompilasi walaupun push mengembalikan sebuah angka. void pada tipe fungsi berarti "apa pun yang dikembalikan, tidak ada yang membacanya". Untuk fungsi yang sama sekali tidak pernah selesai (selalu melempar error atau berulang selamanya), tipe kembaliannya adalah never.
Arrow Function dan Function Expression
Arrow function dan function expression memakai anotasi yang sama. Tipe kembalian ditulis setelah daftar parameter, sebelum =>.
Tanpa tanda kurung, (x, y) => { x, y } adalah sebuah blok tanpa return, dan fungsinya mengembalikan undefined. Aturan runtime untuk arrow function (tidak punya this dan arguments sendiri) sama seperti di JavaScript; lihat arrow function di JavaScript.
Kalau fungsi ditulis langsung sebagai argumen, biasanya parameternya tidak perlu dianotasi sama sekali. TypeScript tahu apa yang diterima callback dari fungsi yang menerimanya (contextual typing): di [1, 2].map(n => n * 2), n sudah bertipe number. Cara menulis tipe sebuah fungsi sebagai nilai, (n: number) => string, dibahas di tipe fungsi.
Mengembalikan Beberapa Nilai
Fungsi hanya mengembalikan satu nilai, jadi kembalikan object atau tuple lalu lakukan destructuring.
Tipe kembalian tuple membutuhkan anotasi. Tanpa anotasi, [a, b] disimpulkan sebagai string[]: destructuring tetap berjalan, tetapi tipenya tidak lagi menyatakan bahwa elemennya tepat dua.
Fungsi Async
Fungsi async selalu mengembalikan Promise. Anotasi tipe kembaliannya sebagai Promise<T>, dengan T adalah nilai yang dikembalikan di dalam fungsi.
async function loadScore(id: number): Promise<number> {
await new Promise((resolve) => setTimeout(resolve, 10));
return id * 10;
}
async function main(): Promise<void> {
const score = await loadScore(4); // score: number
console.log("score", score);
}
main();
Menulis async function f(): number adalah error: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<number>'? (TS1064).
Parameter this
JavaScript menentukan this saat fungsi dipanggil. TypeScript memungkinkanmu menyatakan apa yang harus menjadi this lewat parameter pertama palsu bernama this. Parameter itu dihapus dari JavaScript hasil kompilasi, dan pemanggil tidak mengirimkannya.
interface Counter {
count: number;
}
function increment(this: Counter, by: number): void {
this.count += by;
}
const c = { count: 0, increment };
c.increment(2); // fine: this is c
increment(2);
// error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Counter'.
Tanpa parameter this, this di dalam fungsi yang berdiri sendiri adalah any implisit, dan strict mode melaporkan 'this' implicitly has type 'any' because it does not have a type annotation. (TS2683). Di dalam method class, this sudah bertipe instance class tersebut, jadi parameter ini terutama berguna untuk fungsi berdiri sendiri yang dipasang pada object, dan untuk callback yang dipanggil library dengan this tertentu.
Pertanyaan yang sering diajukan
Bagaimana cara menentukan tipe kembalian fungsi di TypeScript?
Tulis titik dua dan tipenya setelah daftar parameter: function total(a: number, b: number): number { ... }. Untuk arrow function, letaknya sama: const total = (a: number, b: number): number => a + b;. Kalau kamu tidak menuliskannya, TypeScript menyimpulkan tipe kembalian dari pernyataan return.
Apakah tipe kembalian harus selalu dianotasi di TypeScript?
Tidak wajib, karena tipe kembalian bisa disimpulkan. Anotasi tipe kembalian pada fungsi yang di-export dan pada fungsi dengan beberapa jalur return: anotasi itu mendokumentasikan kontraknya, dan return yang salah dilaporkan di dalam fungsi, bukan di pemanggil yang letaknya jauh.
Apa perbedaan void dan undefined di TypeScript?
void berarti "pemanggil tidak boleh memakai nilai kembaliannya". undefined adalah tipe nilai yang nyata. Fungsi yang dideklarasikan (): void tidak boleh mengembalikan nilai, tetapi tipe callback () => void tetap menerima fungsi yang mengembalikan sesuatu, dan hasilnya diabaikan begitu saja. Pakai void untuk fungsi yang tidak mengembalikan apa pun, dan undefined hanya kalau pemanggil memang membandingkan hasilnya dengan undefined.
Bagaimana cara mengembalikan beberapa nilai dari fungsi TypeScript?
Kembalikan sebuah object ({ min: number; max: number }) atau tuple ([number, number]), lalu lakukan destructuring di tempat pemanggilan. Object lebih jelas kalau nilainya punya arti yang berbeda; tuple enak dibaca untuk pasangan pendek seperti [value, setValue].
Apa tipe kembalian fungsi async di TypeScript?
Selalu Promise. Fungsi async yang mengembalikan number punya tipe kembalian Promise<number>, dan menulis : number padanya adalah error kompilasi (TS1064). Fungsi yang tidak mengembalikan apa pun bertipe Promise<void>.