Masukkan Password
18 Type 'Never' di TypeScript
Kita bahas never type di TypeScript pelan-pelan, karena never memang agak membingungkan di awalβterutama kalau dibandingkan dengan void.
1. Apa itu never?
Secara sederhana:
neverberarti sebuah fungsi tidak akan pernah selesai secara normal dengan mengembalikan nilai kepada pemanggilnya.
Contohnya:
function createError(message: string, code: number): never {
throw new Error(message);
}
Fungsi ini memiliki return type never karena fungsi tersebut tidak pernah sampai ke akhir fungsi secara normal.
Kenapa?
Karena ada:
throw new Error(message);
Begitu throw dijalankan, fungsi langsung berhenti dan melempar error.
Jadi tidak ada:
return something;
dan bahkan tidak ada return undefined yang terjadi secara normal.
2. Sebelum memahami never, pahami void
Kita sudah belajar void.
Misalnya:
function greetUser(name: string): void {
console.log("Hello " + name);
}
Fungsi tersebut tidak mengembalikan nilai yang berguna.
Kita bisa melakukan:
greetUser("John");
Output:
Hello John
Kalau kita melakukan:
const result = greetUser("John");
console.log(result);
hasilnya:
Hello John
undefined
Kenapa undefined?
Karena fungsi tersebut selesai menjalankan tugasnya, tetapi tidak menggunakan return untuk mengembalikan nilai.
Secara sederhana:
function dijalankan
β
console.log()
β
fungsi selesai
β
return value = undefined
Jadi:
void= fungsi selesai secara normal, tetapi tidak memberikan nilai yang berguna.
3. Lalu apa bedanya dengan never?
Sekarang kita punya:
function greetUser(name: string): void {
console.log("Hello " + name);
}
dan:
function createError(message: string): never {
throw new Error(message);
}
Perbedaannya sangat penting.
void
Fungsi selesai.
function
β
menjalankan kode
β
selesai
β
undefined
never
Fungsi tidak pernah selesai secara normal.
function
β
menjalankan kode
β
throw error
β
fungsi berhenti secara abnormal
Jadi:
voidβ selesai tanpa return value.neverβ tidak pernah mencapai akhir fungsi secara normal.
4. Contoh paling mudah: throw
Perhatikan:
function createError(
errorMessage: string,
errorCode: number
): never {
throw {
message: errorMessage,
code: errorCode
};
}
Kita bisa memanggil:
createError("Internal Server Error", 500);
Yang terjadi:
createError() dipanggil
β
membuat object error
β
throw object
β
fungsi langsung berhenti
Tidak ada proses seperti:
return something;
Bahkan:
return undefined;
juga tidak terjadi.
5. Kenapa never disebut “never”?
Nama never sebenarnya cukup membantu kalau kita pahami artinya.
never berarti:
“Ini tidak akan pernah terjadi.”
Dalam konteks return function:
“Fungsi ini tidak akan pernah melakukan return secara normal.”
Misalnya:
function createError(): never {
throw new Error("Something went wrong");
}
Kita tidak akan mendapatkan:
const result = createError();
dengan result berisi suatu nilai.
Karena fungsi tersebut melempar error terlebih dahulu.
6. throw membuat fungsi berhenti
Ini bagian yang sangat penting.
Misalnya:
function createError(): never {
throw new Error("Something went wrong");
console.log("Hello");
}
Apakah:
console.log("Hello");
akan dijalankan?
Tidak.
Karena program sudah berhenti di:
throw new Error("Something went wrong");
Jadi kode setelah throw tidak akan pernah dicapai.
throw
β
STOP
β
kode setelahnya tidak dijalankan
Inilah yang disebut unreachable code.
7. Kenapa TypeScript error kalau never tapi fungsi bisa selesai?
Misalnya kita menulis:
function greetUser(): never {
console.log("Hello");
}
TypeScript akan memberikan error.
Kurang lebih maksud errornya:
A function returning
nevercannot have a reachable end point.
Artinya:
Kalau kamu bilang return type-nya
never, maka fungsi tersebut tidak boleh punya jalan untuk mencapai akhir fungsi secara normal.
Karena fungsi ini:
function greetUser(): never {
console.log("Hello");
}
sebenarnya melakukan:
greetUser()
β
console.log()
β
fungsi selesai
Nah, itu bertentangan dengan never.
Kalau fungsi bisa selesai, return type-nya lebih cocok:
void
8. Perhatikan perbandingan ini
void
function greet(): void {
console.log("Hello");
}
Valid.
Karena:
Hello
β
fungsi selesai
β
undefined
never
function greet(): never {
console.log("Hello");
}
β Tidak valid.
Karena fungsi bisa selesai secara normal.
9. Contoh never dengan throw
Ini valid:
function fail(): never {
throw new Error("Something went wrong");
}
Karena:
fail()
β
throw
β
tidak pernah selesai normal
10. Contoh never dengan infinite loop
Ini juga contoh penting dari lecture.
Misalnya:
function infinite(): never {
while (true) {
console.log("Running...");
}
}
Kenapa never?
Karena:
while (true)
akan selalu bernilai true.
Jadi:
while(true)
β
jalan
β
jalan
β
jalan
β
jalan
β
selamanya...
Fungsi tidak pernah mencapai akhir.
Jadi:
function infinite(): never {
while (true) {
console.log("Running...");
}
}
masuk akal.
11. Analogi sederhana
Bayangkan fungsi sebagai sebuah jalan.
void
Jalannya seperti:
START
β
jalan
β
jalan
β
FINISH
Fungsi sampai ke finish.
Tetapi tidak membawa barang apa pun pulang.
Itulah void.
never
Jalannya seperti:
START
β
jalan
β
π¨ ERROR!
β
keluar dari jalan
atau:
START
β
jalan
β
jalan
β
jalan
β
jalan
β
selamanya...
Tidak pernah sampai ke FINISH.
Itulah never.
12. void bukan berarti “tidak ada return sama sekali”
Ini bagian yang sering bikin bingung.
Kalau kita bilang:
function greet(): void {
console.log("Hello");
}
bukan berarti fungsi tersebut secara runtime menghasilkan “tidak ada apa-apa”.
Ketika fungsi selesai, hasil yang diterima JavaScript adalah:
undefined
Contohnya:
function greet(): void {
console.log("Hello");
}
const result = greet();
console.log(result);
Output:
Hello
undefined
Sedangkan never:
function fail(): never {
throw new Error("Failed");
}
fungsi tersebut tidak sampai ke titik setelah pemanggilan secara normal.
Jadi konsepnya:
| Type | Fungsi selesai normal? | Ada nilai return? |
|---|---|---|
void | β Ya | undefined |
never | β Tidak | Tidak pernah return |
13. Kenapa fungsi createError cocok menggunakan never?
Misalnya kita membuat utility function:
function createError(
message: string,
code: number
): never {
throw {
message: message,
code: code
};
}
Kemudian:
createError("Page Not Found", 404);
Fungsi tersebut memang dibuat khusus untuk melempar error.
Dia tidak punya tujuan untuk menghasilkan nilai.
Flow-nya:
createError()
β
buat error object
β
throw
β
STOP
Jadi never mendeskripsikan perilaku fungsi dengan lebih akurat daripada void.
14. Kenapa tidak pakai void saja?
Pertanyaan bagus.
Sebenarnya fungsi yang melakukan throw dapat terlihat seperti tidak menghasilkan nilai:
function createError(message: string, code: number): void {
throw {
message,
code
};
}
Tetapi void hanya mengatakan:
“Fungsi ini tidak memberikan return value yang berguna.”
Sedangkan never mengatakan sesuatu yang lebih spesifik:
“Fungsi ini tidak akan pernah selesai secara normal.”
Itulah perbedaan konsepnya.
15. Analogi restoran π½οΈ
Bayangkan kamu memesan makanan.
void
Koki membuat makanan:
Pesanan
β
diproses
β
selesai
β
tidak ada makanan dikembalikan
Pekerjaan selesai.
Itu seperti void.
never
Tiba-tiba restoran terbakar π¨:
Pesanan
β
diproses
β
π₯ ERROR
β
proses berhenti
Pesanan tidak pernah sampai pada kondisi “selesai normal”.
Itulah never.
16. never berbeda dengan undefined
Ini juga penting.
undefined
undefined adalah sebuah value.
Misalnya:
let value: undefined = undefined;
Ada nilai undefined.
Sedangkan never bukan value yang dikembalikan.
Misalnya:
function fail(): never {
throw new Error("Failed");
}
Tidak ada:
return undefined;
Fungsi bahkan tidak mencapai titik return.
Jadi:
undefined= sebuah nilai.never= tidak pernah menghasilkan nilai karena tidak pernah selesai normal.
17. never juga bisa muncul pada infinite loop
Contoh:
function keepRunning(): never {
while (true) {
console.log("Still running...");
}
}
Tidak ada return.
Kenapa?
Karena fungsi tidak pernah sampai ke akhir.
while(true)
β
true
β
loop
β
true
β
loop
β
true
β
loop
β
β
Maka:
: never
sangat cocok.
18. Hubungannya dengan materi sebelumnya
Kita sekarang sudah belajar beberapa return type.
Misalnya:
function add(a: number, b: number): number {
return a + b;
}
number
Fungsi selesai dan mengembalikan number.
function
β
return 25
β
finish
function getName(): string {
return "John";
}
string
Fungsi selesai dan mengembalikan string.
function greet(): void {
console.log("Hello");
}
void
Fungsi selesai, tetapi tidak mengembalikan nilai yang berguna.
function fail(): never {
throw new Error("Failed");
}
never
Fungsi tidak pernah selesai secara normal.
19. Tabel besar supaya lebih jelas
| Return Type | Contoh | Fungsi selesai normal? | Mengembalikan nilai? |
|---|---|---|---|
number | return 100 | β | β
100 |
string | return "John" | β | β
"John" |
boolean | return true | β | β
true |
void | console.log() | β | undefined |
never | throw new Error() | β | β |
Cara paling mudah mengingatnya:
number β selesai + return number
string β selesai + return string
boolean β selesai + return boolean
void β selesai + tidak ada nilai berguna
never β tidak pernah selesai normal
20. never bukan berarti “fungsi tidak punya return statement”
Ini kesalahan pemahaman yang cukup umum.
Misalnya:
function greet(): void {
console.log("Hello");
}
Tidak ada return, tetapi type-nya void, bukan never.
Jadi:
Tidak adanya
returntidak otomatis berartinever.
Yang menentukan adalah apakah fungsi bisa selesai secara normal atau tidak.
Tidak ada return + fungsi selesai:
function greet(): void {
console.log("Hello");
}
β void
Tidak ada return + infinite loop:
function infinite(): never {
while (true) {}
}
β never
Tidak ada return + throw:
function fail(): never {
throw new Error("Failed");
}
β never
21. Kenapa TypeScript perlu tahu tentang never?
Karena TypeScript perlu memahami flow program.
Contohnya:
function fail(): never {
throw new Error("Failed");
}
function test() {
fail();
console.log("Hello");
}
TypeScript tahu bahwa:
fail();
tidak akan selesai secara normal.
Jadi:
console.log("Hello");
tidak akan pernah dicapai.
Ini membantu TypeScript memahami kode kita dengan lebih akurat.
22. Kapan kita biasanya menggunakan never?
Dalam praktik, beberapa penggunaan umum adalah:
1. Function yang selalu throw
function throwError(message: string): never {
throw new Error(message);
}
2. Infinite loop
function runForever(): never {
while (true) {
// ...
}
}
3. Beberapa kasus advanced TypeScript
never juga sangat penting dalam materi TypeScript yang lebih advanced, terutama ketika nanti belajar:
- exhaustive checking
- discriminated union
- conditional types
- type narrowing
- utility types
Jadi walaupun awalnya terlihat sederhana, never sebenarnya punya peran penting di TypeScript.
23. Hubungkan dengan Union Type
Karena lecture sebelumnya membahas Union Type, ada hubungan menarik dengan never.
Misalnya kita punya:
type Role = "admin" | "user";
Kemudian kita membuat function:
function checkRole(role: Role) {
switch (role) {
case "admin":
return "Admin";
case "user":
return "User";
}
}
Nanti ketika belajar exhaustive checking, never dapat digunakan untuk memastikan semua kemungkinan dalam Union Type sudah ditangani.
Contohnya pola seperti:
function assertNever(value: never): never {
throw new Error("Unexpected value: " + value);
}
Ini memang materi yang lebih advanced, jadi untuk sekarang cukup ingat bahwa never nantinya akan sangat berguna ketika kita menggabungkannya dengan Union Type.
24. Satu hal yang sangat penting: never bukan void
Kalau hanya mengingat satu bagian dari lecture ini, ingat ini:
void
“Saya selesai bekerja, tapi tidak memberikan hasil yang berguna.”
function greet(): void {
console.log("Hello");
}
Fungsi selesai β hasilnya undefined.
never
“Saya tidak pernah selesai bekerja secara normal.”
function fail(): never {
throw new Error("Failed");
}
Fungsi tidak pernah mencapai akhir normal.
25. Cara mengingat dengan kalimat sederhana
Saya sarankan mengingat seperti ini:
void= selesai, tapi tidak membawa hasil.never= tidak pernah selesai secara normal.
Atau versi super singkat:
void β "selesai, tapi kosong"
never β "tidak pernah selesai"
Dan contoh utamanya:
// VOID
function greet(): void {
console.log("Hello");
}
// NEVER
function fail(): never {
throw new Error("Failed");
}
// NEVER
function infinite(): never {
while (true) {
// forever
}
}
Inti lecture
RETURN TYPE
β
ββββββββββββββββ΄βββββββββββββββ
β β
void never
β β
fungsi selesai fungsi tidak pernah
normal selesai secara normal
β β
hasilnya undefined throw / infinite loop
Jadi jangan mengartikan never sebagai “tidak mengembalikan apa pun” saja. Itu masih terlalu mirip dengan void.
Yang lebih tepat:
neverberarti tidak ada kemungkinan fungsi tersebut mencapai akhir dan melakukan return secara normal.