Masukkan Password
17 Tipe Tidak Dikenal (Unknown) di TypeScript
Lecture ini membahas salah satu type khusus di TypeScript, yaitu unknown.
Konsep ini memang sedikit membingungkan di awal karena sekilas unknown terlihat seperti any. Keduanya sama-sama bisa menerima berbagai macam value, tetapi cara TypeScript memperlakukan keduanya sangat berbeda.
Kalau mau dibuat sesederhana mungkin:
any= “Saya bebas melakukan apa saja dengan value ini.”
unknown= “Saya belum tahu value ini apa, jadi cek dulu sebelum menggunakannya.”
Mari kita bahas pelan-pelan.
1. Apa itu unknown?
unknown adalah sebuah type di TypeScript yang digunakan ketika:
Kita belum tahu data yang akan kita terima atau simpan itu bertipe apa.
Contohnya:
let inputVal: unknown;
Artinya:
“Saya belum tahu
inputValnantinya akan berisi apa.”
Bisa saja nanti:
inputVal = 100;
atau:
inputVal = "Hello";
atau:
inputVal = true;
atau:
inputVal = [1, 2, 3];
atau bahkan object:
inputVal = {
name: "John"
};
Semua boleh.
2. unknown mirip dengan any
Sekilas ini terlihat sama dengan:
let inputVal: any;
Karena dengan any kita juga bisa melakukan:
inputVal = 100;
inputVal = "Hello";
inputVal = true;
inputVal = [1, 2, 3];
Dengan unknown juga:
let inputVal: unknown;
inputVal = 100;
inputVal = "Hello";
inputVal = true;
inputVal = [1, 2, 3];
Tidak ada masalah.
Lalu muncul pertanyaan:
Kalau sama-sama bisa menyimpan berbagai macam data, apa bedanya
anydanunknown?
Nah, ini inti dari lecture.
3. Perbedaan utama any dan unknown
Perbedaan paling penting adalah:
anymematikan type checking.
unknowntetap mempertahankan type safety.
Mari kita lihat.
Misalnya:
let inputVal: any = "Hello";
Kemudian:
let username: string = inputVal;
TypeScript akan membolehkan.
Karena inputVal adalah any.
TypeScript berpikir kurang lebih:
“Oh,
any? Ya sudah, saya tidak akan terlalu banyak memeriksa.”
4. Dengan unknown, ceritanya berbeda
Sekarang:
let inputVal: unknown = "Hello";
Kemudian:
let username: string = inputVal;
β TypeScript akan memberikan error.
Kurang lebih:
Type 'unknown' is not assignable to type 'string'
Kenapa?
Karena TypeScript berpikir:
“Tunggu. Kamu bilang
inputValadalahunknown. Saya belum tahu apakah isinya string.”
Walaupun kita sebagai manusia tahu bahwa saat itu isinya "Hello", TypeScript tidak mau langsung percaya.
5. Kenapa TypeScript melakukan itu?
Karena unknown memang dibuat untuk keamanan type.
Bayangkan kita mendapatkan data dari luar aplikasi.
Misalnya:
let inputVal: unknown = getDataFromAPI();
Kita tidak tahu API tersebut akan mengirim:
string?
number?
boolean?
object?
array?
null?
Daripada mengatakan:
let inputVal: any;
yang membuat TypeScript tidak melakukan pengecekan, kita bisa mengatakan:
let inputVal: unknown;
Artinya:
“Saya belum tahu datanya apa. Nanti setelah saya cek, baru saya gunakan.”
Ini jauh lebih aman.
6. Analogi sederhana: paket misterius π¦
Bayangkan kamu menerima sebuah paket.
Kamu belum tahu isinya.
Kamu bisa mengatakan:
Paket ini = unknown
Kamu tidak tahu apakah isinya:
π± HP
π Buku
π Baju
π Apel
Sekarang ada orang berkata:
“Masukkan isi paket ini ke tempat khusus untuk HP.”
Kamu tidak boleh langsung melakukannya.
Kamu harus membuka dan mengecek dulu:
Apa isi paketnya?
β
Buka / cek
β
Apakah HP?
β
Ya β boleh digunakan sebagai HP
Tidak β jangan
Itulah konsep unknown.
7. Dengan any, kamu seperti tidak peduli isi paket
Kalau menggunakan any, kurang lebih seperti:
“Saya tidak tahu isi paketnya, tapi anggap saja semuanya boleh.”
Itulah kenapa any sangat fleksibel, tetapi juga berbahaya.
Contohnya:
let inputVal: any = 100;
let username: string = inputVal;
TypeScript membiarkan.
Padahal:
inputVal = 100
adalah number, bukan string.
Ini bisa menyebabkan bug.
8. unknown memaksa kita melakukan pengecekan
Misalnya:
let inputVal: unknown = "Hello";
let username: string = inputVal;
β Tidak boleh.
Kita harus mengecek terlebih dahulu.
Salah satu caranya menggunakan:
typeof
Contohnya:
if (typeof inputVal === "string") {
username = inputVal;
}
Sekarang TypeScript memahami:
“Oh, di dalam
ifini sudah dipastikan bahwainputValadalah string.”
Jadi aman.
9. Memahami typeof
typeof digunakan untuk mengetahui type sebuah value saat program berjalan.
Contoh:
typeof "Hello"
hasilnya:
"string"
Contoh:
typeof 100
hasil:
"number"
Contoh:
typeof true
hasil:
"boolean"
Contoh:
typeof {}
hasil:
"object"
Jadi kita bisa melakukan:
if (typeof inputVal === "string") {
// inputVal aman digunakan sebagai string
}
10. Contoh lengkap dari lecture
Misalnya:
let inputVal: unknown = 100;
let username: string = "something";
Kita tidak boleh langsung:
username = inputVal;
β Error.
Karena inputVal adalah unknown.
Kita harus melakukan pengecekan:
if (typeof inputVal === "string") {
username = inputVal;
}
Sekarang aman.
11. Apa yang terjadi saat inputVal = 100?
Awalnya:
let inputVal: unknown = 100;
Nilainya:
inputVal
β
100
Kemudian:
if (typeof inputVal === "string") {
username = inputVal;
}
TypeScript melihat:
typeof inputVal
β
"number"
Sedangkan condition meminta:
"string"
Jadi:
typeof inputVal === "string"
adalah:
false
Maka assignment tidak dilakukan.
12. Kemudian inputVal diubah menjadi string
Misalnya:
inputVal = "Hello World";
Sekarang:
inputVal
β
"Hello World"
Kemudian:
if (typeof inputVal === "string") {
username = inputVal;
}
Sekarang:
typeof inputVal
menghasilkan:
"string"
Condition:
typeof inputVal === "string"
menjadi:
true
Maka:
username = inputVal;
boleh dilakukan.
Hasil:
username = "Hello World"
13. Inilah yang disebut Type Narrowing
Ada istilah penting yang mulai muncul di sini:
Type Narrowing
Type narrowing adalah proses mempersempit type dari type yang lebih umum menjadi type yang lebih spesifik setelah kita melakukan pengecekan.
Awalnya:
inputVal: unknown
Kita belum tahu apa-apa.
Kemudian:
if (typeof inputVal === "string") {
TypeScript mengetahui bahwa di dalam blok tersebut:
inputVal
adalah:
string
Jadi:
unknown
β
cek typeof
β
string
Itulah type narrowing.
14. Kenapa unknown lebih aman daripada any?
Bandingkan dua kode ini.
any
let value: any = 100;
let name: string = value;
TypeScript:
β
OK
Padahal sebenarnya:
number β string
tidak cocok.
unknown
let value: unknown = 100;
let name: string = value;
TypeScript:
β Error
TypeScript memaksa kita untuk melakukan pengecekan.
Misalnya:
if (typeof value === "string") {
name = value;
}
Sekarang:
unknown
β
cek
β
string
β
aman
15. Jadi kapan menggunakan unknown?
Gunakan unknown ketika:
Kita memang belum tahu type data yang akan kita terima, tetapi kita tetap ingin TypeScript menjaga type safety.
Contoh situasi yang sering:
Data dari API
const responseData: unknown = getDataFromAPI();
Kita belum tahu response-nya seperti apa.
Input dari user
let input: unknown = getUserInput();
User bisa memberikan berbagai jenis data.
Data dari external library
Kalau sebuah library memberikan data yang belum kita ketahui bentuknya, unknown bisa menjadi pilihan aman.
Data dari JSON
Misalnya kita menerima data eksternal yang belum kita validasi.
Daripada:
const data: any = ...
lebih aman:
const data: unknown = ...
Kemudian kita cek bentuk datanya.
16. Kenapa tidak langsung menggunakan string | number | boolean?
Pertanyaan bagus.
Kalau kita sudah tahu datanya hanya mungkin:
string
atau
number
atau
boolean
maka lebih baik gunakan union:
let value: string | number | boolean;
Karena kita sudah mengetahui kemungkinan type-nya.
unknown digunakan ketika:
Kita benar-benar belum tahu type apa yang akan datang.
Jadi:
Sudah tahu kemungkinan type
β
string | number | boolean
Sedangkan:
Belum tahu sama sekali
β
unknown
17. unknown bukan berarti “semua type bebas digunakan”
Ini kesalahpahaman yang sering terjadi.
Ketika kita menulis:
let value: unknown;
bukan berarti:
“Saya boleh memperlakukan value ini sebagai apa saja.”
Justru sebaliknya.
Artinya:
“Value ini bisa berisi apa saja, tetapi saya tidak boleh menggunakannya sebagai type tertentu sebelum saya memastikan type-nya.”
Ini perbedaan yang sangat penting.
18. Contoh dengan function
Misalnya:
let value: unknown = "Hello";
Kita tidak boleh sembarangan:
value.toUpperCase();
Karena TypeScript belum tahu apakah value adalah string.
Kita harus melakukan:
if (typeof value === "string") {
console.log(value.toUpperCase());
}
Sekarang aman.
19. Contoh dengan number
Misalnya:
let value: unknown = 100;
Kita ingin melakukan:
value + 20;
TypeScript tidak akan mengizinkan secara langsung karena value masih unknown.
Kita bisa:
if (typeof value === "number") {
console.log(value + 20);
}
Di dalam if, TypeScript tahu:
value = number
sehingga operasi tersebut aman.
20. Contoh dengan boolean
let value: unknown = true;
Kita bisa mengecek:
if (typeof value === "boolean") {
console.log(value);
}
Sekarang TypeScript tahu bahwa:
value = boolean
21. Jadi unknown seperti “data yang belum diperiksa”
Cara paling gampang mengingatnya:
unknown
β
"Data ini belum saya kenal"
β
lakukan pengecekan
β
type diketahui
β
boleh digunakan
Misalnya:
unknown
β
typeof value === "string"
β
string
atau:
unknown
β
typeof value === "number"
β
number
22. Perbandingan any dan unknown
any | unknown | |
|---|---|---|
| Bisa menyimpan string | β | β |
| Bisa menyimpan number | β | β |
| Bisa menyimpan object | β | β |
| Bisa menyimpan array | β | β |
Bisa langsung diberikan ke string | β | β |
| Type checking | β Hampir dimatikan | β Tetap aktif |
| Perlu pengecekan sebelum digunakan | β | β |
| Type-safe | β | β |
| Cocok ketika data benar-benar belum diketahui | Kurang ideal | β |
23. Analogi any vs unknown
Bayangkan ada dua kotak.
Kotak any
Labelnya:
π¦ ANY β lakukan apa saja
Kamu bisa memasukkan apa saja dan menggunakannya sebagai apa saja.
Masalahnya:
Bisa salah tanpa ketahuan.
Kotak unknown
Labelnya:
π¦ UNKNOWN β periksa dulu
Kamu boleh memasukkan apa saja.
Tetapi ketika ingin mengambil isinya:
“Cek dulu ini apa.”
Setelah diketahui:
string
baru perlakukan sebagai string.
Setelah diketahui:
number
baru perlakukan sebagai number.
24. Ini alasan unknown sering dianggap lebih baik daripada any
Misalnya kita mendapatkan data dari luar:
const data: unknown = getExternalData();
Kita dipaksa untuk berpikir:
“Data ini sebenarnya apa?”
Misalnya kita menduga data tersebut adalah object:
if (typeof data === "object" && data !== null) {
// lakukan validasi lebih lanjut
}
Dengan pendekatan seperti ini, kita membangun program yang lebih aman.
Kalau kita menggunakan:
const data: any = getExternalData();
kita bisa melakukan apa saja:
data.name;
data.foo.bar;
data.someFunction();
TypeScript mungkin tidak membantu kita ketika ternyata data tersebut tidak sesuai harapan.
25. Kapan sebaiknya tidak menggunakan unknown?
Kalau kita sudah tahu type-nya, gunakan type yang spesifik.
Misalnya:
let username: string;
Kalau kita tahu value selalu number:
let age: number;
Kalau hanya bisa "admin" atau "user":
let role: "admin" | "user";
Jangan menggunakan:
let username: unknown;
kalau sebenarnya kita sudah tahu username pasti string.
Jadi prinsipnya:
Gunakan type paling spesifik yang bisa kamu tentukan.
unknown digunakan ketika type memang belum diketahui.
26. Hubungannya dengan materi sebelumnya
Sebelumnya kita belajar:
any
let value: any;
Artinya:
“TypeScript, jangan terlalu banyak mengecek value ini.”
Sekarang:
unknown
let value: unknown;
Artinya:
“TypeScript, saya belum tahu value ini apa. Tolong jangan izinkan saya menggunakannya sembarangan sampai saya mengeceknya.”
Ini merupakan perbedaan filosofis yang penting.
27. Satu hal penting: unknown bisa menerima hampir semua value
Misalnya:
let value: unknown;
value = "Hello";
value = 100;
value = true;
value = {};
value = [];
Semua bisa.
Tetapi arah sebaliknya tidak sembarangan.
Misalnya:
let value: unknown;
let text: string = value; // β
let number: number = value; // β
let bool: boolean = value; // β
Kita harus memastikan terlebih dahulu.
28. Visualisasi paling sederhana
Pikirkan hubungan seperti ini:
unknown
βββββββββββββββ
β bisa berisi β
β apa saja β
ββββββββ¬βββββββ
β
harus cek
β
ββββββββββββΌβββββββββββ
β β β
string number boolean
β β β
β β β
gunakan gunakan gunakan
Sedangkan any:
any
β
ββββ string
ββββ number
ββββ boolean
ββββ object
ββββ apa saja
Tanpa banyak pemeriksaan.
29. Kesimpulan
Lecture ini sebenarnya ingin menyampaikan satu perbedaan utama:
any
let value: any;
Berarti:
“Saya boleh menyimpan apa saja, dan TypeScript membebaskan saya menggunakan value tersebut tanpa type checking yang ketat.”
Fleksibel, tetapi bisa menyebabkan runtime error.
unknown
let value: unknown;
Berarti:
“Saya belum tahu value ini bertipe apa. Saya boleh menyimpan berbagai macam value, tetapi saya harus mengecek type-nya sebelum menggunakannya sebagai type tertentu.”
Lebih aman.
π§ Cara paling gampang mengingat
Ingat kalimat ini:
any= “terserah”.unknown= “belum tahu, cek dulu”.
Contohnya:
let value: unknown = "Hello";
let username: string;
// β Tidak boleh langsung
username = value;
Harus:
if (typeof value === "string") {
username = value;
}
Flow-nya:
unknown
β
"Belum tahu ini apa"
β
typeof
β
ternyata string
β
aman digunakan sebagai string
Dan inilah alasan utama unknown lebih aman daripada any ketika kita memang belum mengetahui type sebuah data.