Menu

Fungsi di TypeScript: Tipe Parameter, Tipe Kembalian, void

Cara memberi tipe pada fungsi di TypeScript: anotasi setiap parameter, tulis atau biarkan tipe kembalian disimpulkan, pakai void untuk fungsi yang tidak mengembalikan apa pun, dan beri tipe pada arrow function, function expression, fungsi async, serta parameter this.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

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:

SituasiBoleh?
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 ifTidak: 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>.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai