🔒 Getters and Setters
Getters and Setters let you control how a class property is read and updated.
Getter (
get) → Used to read a property's value.Setter (
set) → Used to update a property's value. You can also validate or modify the value before storing it.
Note: They are written like methods but used like normal properties (without
()).
✅ Basic Example
<div class="infographic-gscode">
<style>
.infographic-gscode {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--line: #ddd6c9;
--accent: #2563eb;
--mono-font: 'IBM Plex Mono', 'Courier New', 'Consolas', monospace;
--body-font: 'Inter', -apple-system, sans-serif;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-gscode[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--line: #2c313d;
--accent: #5b8def;
}
.infographic-gscode * { box-sizing: border-box; }
.infographic-gscode .ig-inner { padding: 0; }
.infographic-gscode .vscode {
background: #1e1e1e; border-radius: 8px; overflow: hidden;
box-shadow: 0 8px 20px rgba(0,0,0,0.25); font-family: var(--mono-font);
}
.infographic-gscode .vs-tabbar { display: flex; background: #252526; }
.infographic-gscode .vs-tab {
display: flex; align-items: center; gap: 0.45rem; padding: 0.55rem 1rem;
background: #1e1e1e; border-top: 2px solid #007acc; font-size: 0.78rem; color: #d4d4d4;
}
.infographic-gscode .vs-tab .dot { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: #3178c6; }
.infographic-gscode .vs-body { display: flex; padding: 0.9rem 0; }
.infographic-gscode .vs-gutter {
display: flex; flex-direction: column; padding: 0 0.7rem; color: #6e7681; font-size: 0.78rem;
line-height: 1.5; text-align: right; user-select: none;
}
.infographic-gscode .vs-code {
padding: 0 1rem 0 0.4rem; font-size: 0.78rem; line-height: 1.5; color: #d4d4d4; white-space: pre;
}
.infographic-gscode .kw { color: #569cd6; }
.infographic-gscode .type { color: #4ec9b0; }
.infographic-gscode .var { color: #9cdcfe; }
.infographic-gscode .method { color: #dcdcaa; }
.infographic-gscode .num { color: #b5cea8; }
.infographic-gscode .str { color: #ce9178; }
.infographic-gscode .comment { color: #6a9955; }
.infographic-gscode .punc { color: #d4d4d4; }
.infographic-gscode .exec-line { display: block; border-radius: 4px; padding: 0 0.3rem; margin: 0 -0.3rem; transition: background 0.3s ease; }
.infographic-gscode .exec-line.is-active { background: #2d3f5e; }
.infographic-gscode .exec-line.is-error { background: #4a1f1f; }
.infographic-gscode .call-row { display: flex; justify-content: center; gap: 0.5rem; margin-top: 1.25rem; }
.infographic-gscode .call-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; border: none;
background: #007acc; color: #fff; padding: 0.55rem 1.2rem; border-radius: 999px; cursor: pointer;
}
.infographic-gscode .call-btn:hover:not(:disabled) { opacity: 0.9; }
.infographic-gscode .call-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-gscode .call-btn.ghost { background: transparent; border: 1px solid var(--line); color: var(--ink-soft); }
.infographic-gscode .terminal {
margin-top: 1.1rem; background: #1e1e1e; border-radius: 8px; overflow: hidden;
box-shadow: 0 8px 20px rgba(0,0,0,0.25);
}
.infographic-gscode .term-bar { display: flex; gap: 0.4rem; padding: 0.55rem 0.7rem; background: #2d2d2d; }
.infographic-gscode .term-dot { width: 0.65rem; height: 0.65rem; border-radius: 50%; }
.infographic-gscode .term-dot.red { background: #ff5f56; }
.infographic-gscode .term-dot.yellow { background: #ffbd2e; }
.infographic-gscode .term-dot.green { background: #27c93f; }
.infographic-gscode .term-body {
font-family: var(--mono-font); font-size: 0.85rem; padding: 0.9rem 1rem; min-height: 3.5rem; color: #d4d4d4; line-height: 1.6;
}
.infographic-gscode .term-line { opacity: 0; transform: translateY(4px); transition: opacity 0.25s ease, transform 0.25s ease; }
.infographic-gscode .term-line.is-in { opacity: 1; transform: translateY(0); }
.infographic-gscode .term-prompt { color: #6a9955; }
.infographic-gscode .term-output { color: #6bcf7f; font-weight: 700; }
.infographic-gscode .term-output.is-error { color: #ff6b6b; }
</style>
<div class="ig-inner">
<div class="vscode">
<div class="vs-tabbar"><div class="vs-tab"><span class="dot"></span>Person.ts</div></div>
<div class="vs-body">
<div class="vs-gutter" id="gutter"></div>
<div class="vs-code"><span class="exec-line"><span class="kw">class</span> Person {</span><span class="exec-line"> <span class="kw">private</span> _age: <span class="type">number</span>;</span><span class="exec-line"> constructor(age: <span class="type">number</span>) {</span><span class="exec-line"> <span class="kw">this</span>._age = age;</span><span class="exec-line"> }</span><span class="exec-line"> <span class="kw">get</span> age(): <span class="type">number</span> {</span><span class="exec-line"> <span class="kw">return</span> <span class="kw">this</span>._age;</span><span class="exec-line"> }</span><span class="exec-line"> <span class="kw">set</span> age(value: <span class="type">number</span>) {</span><span class="exec-line"> <span class="kw">if</span> (value < <span class="num">0</span>) {</span><span class="exec-line"> <span class="kw">throw</span> <span class="kw">new</span> <span class="method">Error</span>(<span class="str">"Age cannot be negative"</span>);</span><span class="exec-line"> }</span><span class="exec-line"> <span class="kw">this</span>._age = value;</span><span class="exec-line"> }</span><span class="exec-line">}</span><span class="exec-line" id="line-new"><span class="kw">const</span> p = <span class="kw">new</span> <span class="method">Person</span>(<span class="num">25</span>);</span><span class="exec-line" id="line-get1"><span class="var">console</span>.<span class="method">log</span>(p.age); <span class="comment">// Uses getter</span></span><span class="exec-line" id="line-set"><span class="var">p</span>.age = <span class="num">30</span>; <span class="comment">// Uses setter</span></span><span class="exec-line" id="line-get2"><span class="var">console</span>.<span class="method">log</span>(p.age); <span class="comment">// 30</span></span><span class="exec-line" id="line-bad"><span class="comment">// p.age = -5; // Error</span></span></div>
</div>
</div>
<div class="call-row">
<button class="call-btn" id="playBtn">▶ Run</button>
<button class="call-btn ghost" id="restartBtn">⟲ Restart</button>
</div>
<div class="terminal">
<div class="term-bar"><span class="term-dot red"></span><span class="term-dot yellow"></span><span class="term-dot green"></span></div>
<div class="term-body" id="termBody"></div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-gscode')
|| document.querySelector('.infographic-gscode');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const gutter = wrapper.querySelector('#gutter');
const codeEl = wrapper.querySelector('.vs-code');
const totalLines = codeEl.querySelectorAll('.exec-line').length;
for (let i = 1; i <= totalLines; i++) {
const n = document.createElement('span');
n.textContent = i;
gutter.appendChild(n);
}
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const termBody = wrapper.querySelector('#termBody');
const lineNew = wrapper.querySelector('#line-new');
const lineGet1 = wrapper.querySelector('#line-get1');
const lineSet = wrapper.querySelector('#line-set');
const lineGet2 = wrapper.querySelector('#line-get2');
const lineBad = wrapper.querySelector('#line-bad');
const allExecLines = [lineNew, lineGet1, lineSet, lineGet2, lineBad];
const STEPS = [
{ line: lineNew, log: null },
{ line: lineGet1, log: '25' },
{ line: lineSet, log: null },
{ line: lineGet2, log: '30' },
{ line: lineBad, log: 'Uncaught Error: Age cannot be negative', isError: true }
];
let timer = null;
let idx = -1;
function resetVisual() {
allExecLines.forEach(l => { l.classList.remove('is-active', 'is-error'); });
termBody.innerHTML = '';
}
function addTermLine(text, isError) {
const line = document.createElement('div');
line.className = 'term-line';
line.innerHTML = isError
? `<span class="term-output is-error">${text}</span>`
: `<span class="term-prompt">></span> <span class="term-output">${text}</span>`;
termBody.appendChild(line);
requestAnimationFrame(() => line.classList.add('is-in'));
}
function applyStep(step) {
allExecLines.forEach(l => l.classList.remove('is-active', 'is-error'));
step.line.classList.add(step.isError ? 'is-error' : 'is-active');
if (step.log) addTermLine(step.log, step.isError);
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = '▶ Run';
}
function advance() {
idx++;
if (idx >= STEPS.length) { stop(); return; }
applyStep(STEPS[idx]);
if (idx >= STEPS.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= STEPS.length - 1) restart(false);
playBtn.textContent = '⏸ Pause';
timer = setInterval(advance, 900);
advance();
}
function restart() {
stop();
idx = -1;
resetVisual();
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', restart);
restart();
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});🔍 Explanation
_ageis a private variable, so it cannot be accessed directly.get age()returns the value of_age.set age()updates_ageonly if the value is valid.If a negative age is given, it throws an error.
🤔 Why Use Getters and Setters?
Benefit | Explanation |
|---|---|
✅ Encapsulation | Keeps data private and controlled. |
✅ Validation | Checks values before storing them. |
✅ Better Control | You can format or modify data while getting or setting it. |
✨ Getter Only (Read-Only Property)
Sometimes a value should only be read, not changed.
class Circle {
constructor(private radius: number) {}
get area(): number {
return Math.PI * this.radius ** 2;
}
}
const c = new Circle(10);
console.log(c.area);
// c.area = 100; // Error🔍 Explanation
areais calculated using the radius.Since there is only a getter,
areais read-only.You can access it but cannot assign a new value.
🧠 Another Example
class Config {
private _env: string = "dev";
get env() {
return this._env.toUpperCase();
}
set env(value: string) {
this._env = value.toLowerCase();
}
}
const config = new Config();
config.env = "PROD";
console.log(config.env); // PROD🔍 Explanation
The setter stores the value as lowercase (
"prod").The getter returns it in uppercase (
"PROD").This lets you control how data is stored and displayed.
📝 Best Practices
✅ Use get to return or calculate a value.
✅ Use set to validate or modify input.
✅ Use a private variable (like
_age) to store the actual value.
📌 Summary
Concept | Syntax |
|---|---|
Getter |
|
Setter |
|
Access |
|
Update |
|
Easy Trick:
Getter = Get (Read) 📖
Setter = Set (Write/Update) ✏️
Remember: You use getters and setters like normal properties, not like methods.
person.age; // ✅ Correct
person.age = 30; // ✅ Correct
person.age(); // ❌ Wrong