Masukkan Password
49 Properti Readonly & Opsional di Interface
Lecture ini membahas dua fitur penting pada interface TypeScript:
readonlyproperty pada interface- optional property dan optional parameter
Keduanya terlihat sederhana, tetapi ada beberapa bagian yang sering membingungkan, terutama perbedaan antara:
readonly
dan:
?
serta perbedaan antara optional property dan optional parameter.
1. Gambaran besar dulu
Bayangkan kita punya interface:
interface User {
firstName: string;
lastName: string;
company: string;
}
Artinya setiap class yang:
implements User
harus memiliki:
firstName
lastName
company
Nah, kita bisa memberikan aturan tambahan.
readonly
readonly company: string;
Artinya:
companywajib ada dan setelah nilainya ditetapkan, tidak boleh diubah melalui tipe/interface tersebut.
?
location?: string;
Artinya:
locationboleh ada, boleh juga tidak ada.
Jadi:
readonly → apakah property boleh diubah?
? → apakah property wajib ada?
Ini mental model yang sangat bagus untuk diingat.
2. readonly pada interface
Misalnya:
interface User {
firstName: string;
lastName: string;
readonly company: string;
}
Artinya User harus memiliki:
firstName → wajib
lastName → wajib
company → wajib
tetapi readonly
Transcript menggunakan contoh company sebagai property readonly pada interface.
3. Class yang implements interface tetap harus punya property tersebut
Misalnya:
class Admin implements User {
firstName = "John";
lastName = "Smith";
company = "Google";
}
Ini valid.
Kenapa?
Karena Admin memiliki semua property yang diwajibkan User.
User
│
├── firstName
├── lastName
└── readonly company
↓
Admin
│
├── firstName
├── lastName
└── company
Tapi ada hal yang cukup menarik.
4. readonly pada interface tidak otomatis membuat property class menjadi readonly
Ini bagian yang sangat penting dari lecture.
Kita punya:
interface User {
readonly company: string;
}
Lalu:
class Admin implements User {
company = "Google";
}
Kemudian:
const admin = new Admin();
admin.company = "Microsoft";
Dalam contoh transcript, ini tetap diperbolehkan karena property company pada Admin sendiri tidak dideklarasikan sebagai readonly.
Jadi jangan berpikir:
“Kalau interface bilang readonly, otomatis property di class juga readonly.”
Tidak seperti itu dalam konteks contoh ini.
5. Kenapa bisa begitu?
Karena TypeScript membedakan antara:
Admin
dan:
User
Misalnya:
const admin: Admin = new Admin();
admin.company = "Microsoft";
Compiler melihat:
“Variable ini bertipe
Admin.”
Kalau Admin mendeklarasikan:
company: string;
maka property tersebut masih writable.
Tetapi kalau:
const admin: User = new Admin();
maka compiler melihat admin sebagai User.
Dan User mengatakan:
readonly company: string;
Maka:
admin.company = "Microsoft";
akan error.
Transcript menunjukkan perubahan ini secara eksplisit: ketika instance Admin disimpan dalam variable yang bertipe User, assignment ke company ditolak karena interface mendeklarasikannya sebagai readonly.
6. Ini sangat penting: deklarasi type memengaruhi apa yang compiler izinkan
Bandingkan:
Kasus 1
const admin: Admin = new Admin();
admin.company = "Microsoft";
Compiler melihat:
admin → Admin
Jika Admin.company bukan readonly, maka boleh.
Kasus 2
const admin: User = new Admin();
admin.company = "Microsoft";
Compiler melihat:
admin → User
Dan User mengatakan:
readonly company
Maka:
admin.company = ...
↓
ERROR
Ini contoh yang sangat bagus tentang bagaimana static type TypeScript memengaruhi akses kita terhadap object.
7. Analogi sederhana readonly
Bayangkan ada dokumen perusahaan:
Company: Google
Aturannya:
“Ketika kamu melihat dokumen ini melalui kontrak
User, informasi company tidak boleh diedit.”
Jadi:
User
↓
readonly company
↓
boleh membaca
tidak boleh mengubah
Mirip dengan konsep readonly yang sudah kita bahas sebelumnya.
8. Sekarang masuk ke Optional Property
Sekarang kita punya:
interface User {
firstName: string;
lastName: string;
readonly company: string;
location: string;
}
Karena location tidak memiliki ?, maka:
locationwajib dimiliki.
Kalau:
class Admin implements User {
firstName = "John";
lastName = "Smith";
company = "Google";
}
akan error.
Kenapa?
Karena kurang:
location
9. Membuat property menjadi optional
Caranya sangat sederhana:
location?: string;
Tanda:
?
berarti:
Property ini optional.
Jadi:
interface User {
firstName: string;
lastName: string;
readonly company: string;
location?: string;
}
Sekarang Admin tidak wajib memiliki location.
class Admin implements User {
firstName = "John";
lastName = "Smith";
company = "Google";
}
Valid.
Karena:
firstName → wajib ✓
lastName → wajib ✓
company → wajib ✓
location → optional
Transcript menjelaskan bahwa ? digunakan untuk menjadikan property interface optional.
10. Optional bukan berarti harus punya nilai null
Ini juga penting.
Kalau:
location?: string;
bukan berarti:
location = null;
Yang dimaksud adalah:
location boleh ada
atau
location tidak ada
Contoh:
const user1 = {
firstName: "John",
lastName: "Smith",
company: "Google"
};
Valid.
Sedangkan:
const user2 = {
firstName: "John",
lastName: "Smith",
company: "Google",
location: "London"
};
juga valid.
Karena location optional.
11. ? bisa digunakan di class juga
Konsep yang sama berlaku pada class.
Misalnya:
class User {
firstName: string;
lastName: string;
location?: string;
}
Artinya:
location
↓
optional property
Jadi object/class tersebut tidak harus memiliki nilai location.
Transcript juga menjelaskan bahwa optional property dapat digunakan langsung pada class dengan syntax yang sama, yaitu ?.
12. Optional property vs optional parameter
Nah, sekarang kita masuk bagian yang agak berbeda.
Ada:
location?: string;
Ini property.
Sedangkan:
constructor(
firstName: string,
lastName: string,
location?: string
) {}
Ini parameter.
Keduanya sama-sama menggunakan ?, tetapi tempat penggunaannya berbeda.
13. Optional property
Contoh:
class Member {
firstName: string;
lastName: string;
location?: string;
}
Artinya:
Object
Memberboleh memilikilocation, tetapi tidak wajib.
14. Optional constructor parameter
Misalnya kita punya:
class Member {
constructor(
public firstName: string,
public lastName: string,
public location: string
) {}
}
Karena location wajib, ketika membuat object:
const member = new Member(
"Mary",
"Jane"
);
akan error.
Karena constructor meminta tiga argument:
1. firstName
2. lastName
3. location
15. Membuat parameter menjadi optional
Kita bisa menulis:
class Member {
constructor(
public firstName: string,
public lastName: string,
public location?: string
) {}
}
Sekarang kita boleh:
const member1 = new Member(
"Mary",
"Jane",
"London"
);
atau:
const member2 = new Member(
"John",
"Smith"
);
Keduanya valid.
Karena:
location?: string
berarti parameter location tidak wajib diberikan.
Transcript menjelaskan tepat konsep ini: parameter constructor dapat dibuat optional menggunakan ?, sehingga pemanggil boleh memberikan nilai atau menghilangkannya.
16. Kalau parameter optional tidak diberikan, nilainya apa?
Secara default:
undefined
Misalnya:
class Member {
constructor(
public name: string,
public location?: string
) {}
}
const member = new Member("John");
Maka secara konsep:
member.name
// "John"
member.location
// undefined
Karena kita tidak memberikan location.
Transcript juga menjelaskan bahwa ketika optional parameter tidak diberikan, nilainya menjadi undefined.
17. Lalu bagaimana memberikan nilai default?
Ini bagian yang cukup penting karena transcript memperlihatkan error ketika mencoba melakukan:
location?: string = "London"
❌ Tidak boleh.
Jangan menggabungkan ? dan default value seperti itu.
Kalau ingin parameter optional sekaligus punya default value, gunakan:
location: string = "London"
Bukan:
location?: string = "London"
Contoh:
constructor(
public firstName: string,
public lastName: string,
public location: string = "London"
) {}
Sekarang:
const member1 = new Member(
"Mary",
"Jane",
"Paris"
);
hasil:
location = Paris
Tetapi:
const member2 = new Member(
"John",
"Smith"
);
hasil:
location = London
Karena default value digunakan.
18. Kenapa ? tidak diperlukan kalau ada default value?
Karena default parameter sudah otomatis membuat argument tersebut tidak wajib diberikan.
Misalnya:
function greet(name: string = "John") {
console.log(name);
}
Kita boleh:
greet();
dan:
greet("Mary");
Jadi tidak perlu:
name?: string = "John"
Cukup:
name: string = "John"
19. Ada satu detail penting dari transcript
Transcript kemudian menunjukkan bahwa kita bisa memberikan nilai awal pada property:
location: string = "London";
Misalnya:
class Member {
location: string = "London";
constructor(
public firstName: string,
public lastName: string,
location?: string
) {
if (location) {
this.location = location;
}
}
}
Secara konsep:
Tidak ada location
↓
gunakan "London"
Ada location
↓
gunakan location yang diberikan
Namun perlu diperhatikan: source lecture hanya menjelaskan konsep ini secara sederhana, bukan membahas seluruh variasi implementasi default property/constructor secara mendalam.
20. Bedakan tiga hal ini
Ini bagian yang sangat penting untuk kamu hafalkan.
A. Required property
location: string;
Artinya:
Harus ada.
B. Optional property
location?: string;
Artinya:
Boleh ada, boleh tidak.
C. Property dengan default value
location: string = "London";
Artinya:
Property punya nilai awal
"London".
Secara mental:
location: string
↓
WAJIB
location?: string
↓
BOLEH TIDAK ADA
location: string = "London"
↓
ADA NILAI DEFAULT
21. readonly dan ? bisa digabung
Ini kombinasi yang sangat berguna.
Misalnya:
interface User {
readonly id: number;
name: string;
location?: string;
}
Artinya:
id
↓
wajib ada
tidak boleh diubah
name
↓
wajib ada
boleh diubah
location
↓
tidak wajib ada
kalau ada, boleh diubah
Kalau:
readonly location?: string;
maka:
location
↓
tidak wajib ada
dan
kalau ada tidak boleh diubah
Jadi readonly dan ? mengatur dua hal yang berbeda.
22. Analogi formulir pendaftaran
Bayangkan formulir:
Nama : __________
Email : __________
Perusahaan : __________
Alamat : __________
Kita bisa membuat aturan:
interface User {
name: string;
email: string;
readonly company: string;
location?: string;
}
Artinya:
name
name: string
Wajib diisi.
email
email: string
Wajib diisi.
company
readonly company: string
Wajib diisi, tetapi setelah ditetapkan tidak boleh diedit melalui tipe tersebut.
location
location?: string
Tidak wajib diisi.
Jadi interface seperti formulir aturan.
23. Hubungkan dengan materi interface sebelumnya
Sebelumnya kita belajar:
interface User {
firstName: string;
lastName: string;
greetUser(): void;
}
Kemudian:
class Admin implements User
berarti:
Admin harus mengikuti kontrak User.
Sekarang kontraknya bisa lebih canggih:
interface User {
firstName: string;
lastName: string;
readonly company: string;
location?: string;
greetUser(): void;
}
Jadi interface sekarang bisa mengatakan:
firstName
↓
wajib
lastName
↓
wajib
company
↓
wajib + readonly
location
↓
optional
greetUser()
↓
wajib
Ini membuat kontrak menjadi jauh lebih fleksibel.
24. Kesalahan yang sering dilakukan pemula
Kesalahan 1
readonly company: string = "Google";
di interface.
Interface hanya mendeklarasikan struktur, bukan memberikan implementation/value.
Kesalahan 2
Mengira readonly interface otomatis membuat class property readonly dalam semua konteks.
Contoh lecture justru menunjukkan bahwa:
class Admin implements User {
company = "Google";
}
masih dapat diubah jika object dipandang sebagai Admin.
Kesalahan 3
Mengira ? berarti nilainya null.
Tidak.
Optional berarti nilai/property tersebut boleh tidak ada, dan dalam contoh parameter yang tidak diberikan, nilainya menjadi undefined.
Kesalahan 4
Menulis:
location?: string = "London";
❌ Tidak valid.
Gunakan:
location: string = "London";
untuk default parameter.
25. Ringkasan perbedaan readonly, ?, dan default value
| Syntax | Maksud |
|---|---|
name: string | wajib ada |
name?: string | tidak wajib ada |
readonly name: string | wajib ada + tidak boleh di-reassign melalui tipe tersebut |
readonly name?: string | tidak wajib ada + kalau ada tidak boleh di-reassign |
name: string = "John" | punya default value |
Cara mengingat:
? → "harus ada nggak?"
readonly → "boleh diubah nggak?"
= value → "kalau tidak diberikan, pakai apa?"
Ini menurut saya adalah mental model terbaik untuk materi lecture ini.
26. Kesimpulan
Materi ini sebenarnya mengajarkan bahwa interface tidak hanya bisa mengatakan:
“Object harus punya property ini.”
Tetapi kita juga bisa membuat kontraknya lebih spesifik:
interface User {
firstName: string;
lastName: string;
readonly company: string;
location?: string;
}
Artinya:
User
│
┌─────────┼─────────┐
↓ ↓ ↓
firstName company location
│ │ │
wajib wajib optional
│ readonly │
│ │ │
└──────────┴──────────┘
Kemudian class:
class Admin implements User
harus memenuhi kontrak tersebut.
Dan untuk constructor, kita bisa membuat parameter optional:
constructor(
firstName: string,
lastName: string,
location?: string
) {}
atau memberikan default:
constructor(
firstName: string,
lastName: string,
location: string = "London"
) {}
Jadi tiga keyword/syntax yang perlu benar-benar kamu pahami adalah:
readonly= tidak boleh diubah?= tidak wajib ada= value= nilai default
Kalau tiga konsep ini sudah jelas, bagian interface berikutnya akan jauh lebih mudah dipahami.