Masukkan Password
16 Tipe Fungsi untuk Panggilan Balik (Callback)
1. Review: Function Type pada variable
Di lecture sebelumnya kita belajar bahwa sebuah variable bisa memiliki type berupa function.
Misalnya:
let addNumbers: (num1: number, num2: number) => number;
Artinya addNumbers hanya boleh diisi oleh function yang:
- menerima parameter pertama
number - menerima parameter kedua
number - mengembalikan
number
Kita bisa menyebutnya sebagai function signature.
Bentuknya:
(number, number) → number
2. Contoh sum
Misalnya kita punya:
function sum(num1: number, num2: number): number {
return num1 + num2;
}
Signature-nya:
(number, number) → number
Sama dengan yang dibutuhkan addNumbers:
let addNumbers: (num1: number, num2: number) => number;
Maka ini valid:
addNumbers = sum;
Karena signature-nya cocok.
3. Function add tidak cocok
Misalnya ada:
function add(num1: number, num2: number): void {
console.log(num1 + num2);
}
Function ini menerima:
number, number
Tetapi return-nya:
void
Jadi signature-nya:
(number, number) → void
Sedangkan addNumbers membutuhkan:
(number, number) → number
Karena return type berbeda:
addNumbers:
(number, number) → number
add:
(number, number) → void
maka:
addNumbers = add;
❌ Error.
4. Sampai sini sebenarnya sudah kita pelajari sebelumnya
Nah, sekarang lecture membawa kita ke konsep baru:
Bagaimana kalau function type tersebut digunakan pada parameter function?
Contohnya:
function getResult(
num1: number,
num2: number,
print: ...
) {
}
Parameter ketiga bernama:
print
Dan kita ingin print berisi sebuah function.
5. Apa itu Callback Function?
Sebelum masuk ke TypeScript, kita pahami dulu istilah callback.
Callback adalah:
Function yang kita kirimkan ke function lain sebagai argument, lalu function tersebut akan memanggil callback tadi.
Contoh sederhana JavaScript:
function process(callback) {
callback();
}
Kemudian:
function sayHello() {
console.log("Hello");
}
Kita bisa melakukan:
process(sayHello);
Flow-nya:
sayHello
↓
dikirim ke process
↓
process menerima sayHello
↓
callback()
↓
sayHello dijalankan
Jadi sayHello disebut callback function.
6. Kembali ke contoh lecture
Kita ingin membuat function:
function getResult(
num1: number,
num2: number,
print: ...
) {
}
Function ini akan:
- menerima
num1 - menerima
num2 - menghitung
num1 + num2 - memanggil function
print - mengirimkan hasil perhitungan ke
print
Misalnya:
getResult(12, 13, display)
Maka:
getResult
│
├── num1 = 12
├── num2 = 13
└── print = display function
Kemudian:
print("Sum equals", result);
akan memanggil display.
7. Masalahnya kalau print tidak diberi type
Misalnya kita menulis:
function getResult(
num1: number,
num2: number,
print
) {
const result = num1 + num2;
print("Sum equals", result);
}
Kalau print tidak diberi type yang jelas, TypeScript bisa memperlakukannya sebagai any dalam konteks tertentu.
Artinya kita bisa memberikan apa saja:
getResult(12, 13, 100);
atau:
getResult(12, 13, "hello");
atau:
getResult(12, 13, true);
Padahal kita sebenarnya menginginkan:
print harus berupa function
Dan bukan sembarang function.
8. Kita ingin menentukan signature print
Dari kode:
print("Sum equals", result);
kita bisa mengetahui bahwa function print harus menerima dua parameter.
Parameter pertama:
"Sum equals"
adalah string.
Jadi:
string
Parameter kedua:
result
adalah number.
Jadi:
number
Dan kita ingin print hanya menampilkan sesuatu, tidak mengembalikan value.
Jadi return type:
void
Maka function signature yang kita butuhkan adalah:
(message: string, result: number) => void
9. Memberikan Function Type kepada parameter
Sekarang kita bisa menulis:
function getResult(
num1: number,
num2: number,
print: (message: string, result: number) => void
) {
const result = num1 + num2;
print("Sum equals", result);
}
Ini adalah inti dari lecture.
Parameter:
print
memiliki type:
(message: string, result: number) => void
Artinya:
- parameter pertama
string- parameter kedua
numberdan return type-nya
void.
10. Kita membuat function display
Sekarang kita buat function yang cocok dengan signature tersebut:
function display(message: string, result: number): void {
console.log(message + " " + result);
}
Perhatikan signature-nya:
(string, number) → void
Sedangkan getResult membutuhkan:
(string, number) → void
Cocok.
Maka kita bisa:
getResult(12, 13, display);
11. Apa yang terjadi di dalamnya?
Mari kita jalankan secara perlahan.
Kita memanggil:
getResult(12, 13, display);
Maka:
num1 = 12
num2 = 13
print = display
Kemudian:
const result = num1 + num2;
hasilnya:
result = 25
Kemudian:
print("Sum equals", result);
Karena:
print = display
maka sebenarnya yang dipanggil adalah:
display("Sum equals", 25);
Kemudian display melakukan:
console.log(message + " " + result);
Hasil:
Sum equals 25
12. Gambarkan flow-nya seperti ini
Ini mungkin cara paling mudah untuk memahaminya:
getResult(12, 13, display)
│
├── num1 = 12
├── num2 = 13
└── print = display
│
↓
result = 12 + 13
│
↓
25
│
↓
print("Sum equals", 25)
│
↓
display("Sum equals", 25)
│
↓
console.log(...)
│
↓
"Sum equals 25"
13. Kenapa ini disebut callback?
Karena display diberikan kepada getResult:
getResult(12, 13, display);
display belum kita jalankan secara langsung.
Kita hanya memberikannya kepada getResult.
Kemudian getResult yang memutuskan kapan display dijalankan:
print("Sum equals", result);
Jadi:
display
↓
dikirim ke getResult
↓
getResult menyimpannya di parameter print
↓
getResult memanggil print()
↓
display dijalankan
Itulah callback.
14. Kenapa Function Type sangat berguna di sini?
Karena tanpa Function Type, TypeScript tidak tahu apa yang boleh diberikan ke parameter print.
Dengan:
print: (message: string, result: number) => void
TypeScript sekarang memiliki aturan yang jelas.
Ini valid:
function display(message: string, result: number): void {
console.log(message + result);
}
getResult(12, 13, display);
Karena signature cocok.
Ini tidak valid:
getResult(12, 13, 100);
Karena 100 bukan function.
❌ Error.
Ini juga tidak valid:
getResult(12, 13, "hello");
Karena "hello" adalah string.
❌ Error.
15. Bagaimana kalau kita memberikan function yang salah?
Misalnya:
function wrongFunction(name: string): void {
console.log(name);
}
Kemudian:
getResult(12, 13, wrongFunction);
TypeScript akan menolak.
Kenapa?
Karena getResult membutuhkan:
(string, number) → void
Tetapi wrongFunction memiliki:
(string) → void
Jumlah parameter tidak sesuai.
Contoh lain:
function wrongFunction(
message: string,
result: string
): void {
console.log(message + result);
}
Ini juga tidak cocok.
Karena yang dibutuhkan:
(string, number) → void
sedangkan function tersebut:
(string, string) → void
Parameter kedua salah.
Contoh lain:
function wrongFunction(
message: string,
result: number
): number {
return result;
}
Ini juga berbeda karena return type-nya:
number
sedangkan yang dibutuhkan:
void
16. Jadi ada tiga hal yang harus cocok
Saat kita memberikan callback kepada parameter yang memiliki Function Type, TypeScript akan memastikan bentuk function-nya sesuai.
Misalnya:
(message: string, result: number) => void
Kita bisa memecahnya menjadi:
1. Jumlah parameter
Harus sesuai dengan yang dibutuhkan.
2. Type parameter
Harus sesuai.
message → string
result → number
3. Return type
Harus sesuai.
void
17. Hubungannya dengan materi sebelumnya
Sebenarnya konsep ini sangat mirip dengan lecture sebelumnya.
Sebelumnya:
let addNumbers: (num1: number, num2: number) => number;
Kita menentukan:
Variable
addNumbershanya boleh menyimpan function dengan signature tertentu.
Sekarang:
function getResult(
num1: number,
num2: number,
print: (message: string, result: number) => void
) {
}
Kita menentukan:
Parameter
Jadi perbedaannya hanya function type-nya ditempatkan di mana.
Pada variable:
let fn: (number) => void;
Pada parameter:
function test(fn: (number) => void) {}
18. Callback bisa membuat function menjadi sangat fleksibel
Ini salah satu alasan callback banyak digunakan.
Misalnya getResult bertugas menghitung:
const result = num1 + num2;
Tetapi getResult tidak perlu tahu bagaimana hasil tersebut akan ditampilkan.
Kita bisa menentukan dari luar.
Misalnya:
function display(message: string, result: number): void {
console.log(message + ": " + result);
}
Lalu:
getResult(12, 13, display);
Atau kita bisa membuat callback lain:
function displayWithStars(
message: string,
result: number
): void {
console.log("*** " + message + ": " + result + " ***");
}
Kemudian:
getResult(12, 13, displayWithStars);
Function getResult tidak perlu diubah.
Karena kedua callback memenuhi kontrak:
(string, number) => void
19. Analogi sederhana: pesan + kurir 📦
Bayangkan getResult adalah sebuah toko.
Toko menghitung:
12 + 13 = 25
Toko tidak peduli siapa yang mengantarkan hasilnya.
Toko hanya berkata:
“Saya membutuhkan kurir yang punya aturan: menerima pesan berupa string dan hasil berupa number.”
Itulah:
(message: string, result: number) => void
Kita bisa memberikan kurir A:
display
atau kurir B:
displayWithStars
Selama keduanya memenuhi aturan.
Jadi:
getResult
│
menghasilkan 25
│
membutuhkan callback
│
┌────────┴────────┐
↓ ↓
display displayWithStars
│ │
└───────┬─────────┘
↓
sama-sama memenuhi
(string, number) => void
20. Callback tidak harus memiliki nama
Kita juga bisa langsung memberikan arrow function.
Misalnya:
getResult(12, 13, (message, result) => {
console.log(message + ": " + result);
});
Di sini kita tidak membuat:
function display() {}
terlebih dahulu.
Kita langsung memberikan function sebagai argument.
Karena TypeScript sudah tahu bahwa parameter ketiga membutuhkan:
(message: string, result: number) => void
TypeScript juga bisa mengetahui type message dan result.
Jadi callback seperti ini sangat umum:
getResult(12, 13, (message, result) => {
console.log(message + ": " + result);
});
21. Contoh yang lebih sederhana
Supaya konsep callback benar-benar melekat, lihat contoh ini:
function calculate(
a: number,
b: number,
callback: (result: number) => void
) {
const result = a + b;
callback(result);
}
Kita membuat callback:
function showResult(result: number): void {
console.log("Result:", result);
}
Kemudian:
calculate(10, 20, showResult);
Flow:
calculate
↓
10 + 20
↓
30
↓
callback(30)
↓
showResult(30)
↓
Result: 30
Ini adalah pola callback yang sangat umum.
22. Hal yang perlu kamu ingat tentang void
Di lecture ini ada:
(message: string, result: number) => void
void berarti callback tersebut tidak diharapkan menghasilkan value yang digunakan oleh pemanggil.
Contohnya:
function display(
message: string,
result: number
): void {
console.log(message, result);
}
Tidak ada:
return ...
Jadi:
input:
string + number
output:
void
23. Kesalahan yang sering terjadi
❌ Hanya menulis Function
Misalnya:
function getResult(
a: number,
b: number,
callback: Function
) {}
Ini memang mengatakan callback harus berupa function.
Tetapi terlalu umum.
Function apa pun bisa masuk.
Lebih baik:
function getResult(
a: number,
b: number,
callback: (result: number) => void
) {}
Sekarang TypeScript tahu bentuk callback yang diharapkan.
24. Cara membaca syntax-nya
Kalau kamu melihat:
callback: (message: string, result: number) => void
jangan bingung.
Pecah saja:
callback
↓
nama parameter
Kemudian:
(message: string, result: number) => void
adalah type-nya.
Artinya:
callback harus berupa function
↓
menerima message: string
↓
menerima result: number
↓
return void
Jadi keseluruhannya:
Parameter
callbackharus berupa function yang menerimastringdannumber, kemudian returnvoid.
25. Kesimpulan besar lecture
Ada dua konsep yang harus kamu bedakan.
Function Type pada variable
let addNumbers: (a: number, b: number) => number;
Artinya:
Variable
addNumbershanya boleh menyimpan function dengan signature tersebut.
Function Type pada parameter
function getResult(
a: number,
b: number,
callback: (result: number) => void
) {}
Artinya:
Parameter
callbackhanya boleh menerima function dengan signature tersebut.
Dan ketika function diberikan sebagai argument:
getResult(10, 20, showResult);
showResult disebut callback function.
🧠 Ringkasan paling penting
Ingat pola berikut:
function namaFunction(
parameter: (parameterType) => returnType
) {
}
Contoh:
function process(
number: number,
callback: (result: number) => void
) {
callback(number);
}
Artinya:
process
│
├── number: number
│
└── callback:
│
├── menerima number
└── return void
Kemudian:
function show(result: number): void {
console.log(result);
}
process(100, show);
show adalah callback dan TypeScript memastikan signature-nya sesuai.
Kalimat kunci untuk materi ini:
Function Type tidak hanya bisa digunakan untuk menentukan type sebuah variable, tetapi juga bisa digunakan untuk menentukan function seperti apa yang boleh diberikan sebagai parameter. Function yang diberikan sebagai parameter tersebut disebut callback function.
Kalau kamu sudah memahami pola callback: (parameter: type) => returnType, berarti inti lecture ini sudah kamu kuasai.