When a class implements an interface:
✅ It agrees to follow the contract (shape and behavior) described by the interface.
❌ If it misses any properties or methods, TypeScript will throw an error.
✅ Basic Syntax
interface Greetable {
name: string;
greet(msg: string): void;
}
class Person implements Greetable {
name: string;
constructor(name: string) {
this.name = name;
}
greet(msg: string): void {
console.log(`${msg}, I’m ${this.name}`);
}
}
const user = new Person("Codeveda");
user.greet("Hello"); // Output: Hello, I’m Codeveda🧠 Key Rules
All required properties and methods in the interface must be defined in the class.
You can also add extra methods or properties in the class (TypeScript won’t complain).
✨ Optional & Readonly Interface Members
interface User {
readonly id: number; //readonly
username: string;
email?: string; //optional
}
class Admin implements User {
readonly id: number;
username: string;
email?: string;
constructor(id: number, username: string, email?: string) {
this.id = id;
this.username = username;
this.email = email;
}
}✅ If a property is marked readonly in the interface, it must be readonly in the class too.
🔁 Implementing Multiple Interfaces
interface Printable {
print(): void;
}
interface Savable {
save(): void;
}
class Report implements Printable, Savable {
print() {
console.log("Printing report...");
}
save() {
console.log("Saving report...");
}
}🧱 Real-World Example: Button Component Interface
<div class="infographic-ts" id="infographic-ts">
<style>
.infographic-ts {
--body-font: system-ui, -apple-system, sans-serif;
--mono-font: ui-monospace, SFMono-Regular, Consolas, "Courier New", monospace;
--ed-bg: #1e1e1e;
--ed-bar: #2a2a2a;
--ed-out: #d4d4d4;
--ed-muted: #8a8a8a;
--ed-ok: #4ec9b0;
--tok-kw: #c586c0;
--tok-type: #4ec9b0;
--tok-str: #ce9178;
--tok-cmt: #808080;
--tok-var: #ffffff;
--accent: #2563eb;
max-width: 680px;
margin: 0 auto;
box-sizing: border-box;
background: transparent;
font-family: var(--body-font);
}
.infographic-ts * { box-sizing: border-box; }
.ts-header { font-family: 'Georgia', 'Fraunces', serif; font-weight: 700;
font-size: 1.9rem; letter-spacing: 0.01em; color: inherit; text-align: center;
margin: 0 0 1.4rem; }
.code-window { background: var(--ed-bg); border: 1px solid #2f2f2f; border-radius: 8px;
overflow: hidden; margin-bottom: 1rem; }
.code-topbar { display: flex; align-items: center; justify-content: space-between;
padding: 0.5rem 0.75rem; background: var(--ed-bar); }
.code-dots { display: flex; gap: 6px; }
.code-dot { width: 9px; height: 9px; border-radius: 50%; }
.code-dot.r { background: #ff5f57; }
.code-dot.y { background: #febc2e; }
.code-dot.g { background: #28c840; }
.code-filename { font-family: var(--mono-font); font-size: 0.74rem; color: var(--ed-muted); }
.code-body { padding: 0.85rem 1.1rem; font-family: var(--mono-font); font-size: 0.8rem;
line-height: 1.65; color: var(--ed-out); white-space: pre; overflow-x: auto; }
.tok-kw { color: var(--tok-kw); }
.tok-type { color: var(--tok-type); }
.tok-str { color: var(--tok-str); }
.tok-cmt { color: var(--tok-cmt); }
.tok-var { color: var(--tok-var); }
.tok-punc { color: var(--tok-var); }
.output-frame { background: #ffffff; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;
box-shadow: 0 6px 18px rgba(0,0,0,0.18); }
.output-bar { display: flex; align-items: center; justify-content: space-between;
padding: 0.5rem 0.75rem; background: #2a2a2a; }
.output-label { font-family: var(--mono-font); font-size: 0.74rem; color: var(--ed-muted); }
.output-screen { padding: 2.75rem 1rem; display: flex; align-items: center; justify-content: center;
background: #fafafa; min-height: 110px; }
.demo-btn { font-family: var(--body-font); font-size: 0.95rem; font-weight: 600; color: #fff;
background: var(--accent); border: none; border-radius: 6px; padding: 0.7rem 1.7rem;
cursor: pointer; box-shadow: 0 2px 8px rgba(37, 99, 235, 0.35); transition: transform 0.1s ease, opacity 0.15s ease; }
.demo-btn:hover { opacity: 0.92; }
.demo-btn:active { transform: scale(0.96); }
.terminal { background: var(--ed-bg); border-radius: 8px; overflow: hidden;
box-shadow: 0 6px 18px rgba(0,0,0,0.25); }
.term-body { font-family: var(--mono-font); font-size: 0.82rem; padding: 0.85rem 1.1rem;
min-height: 3rem; color: var(--ed-out); line-height: 1.7; }
.term-line { opacity: 0; transform: translateY(4px); transition: opacity 0.25s ease, transform 0.25s ease; }
.term-line.is-in { opacity: 1; transform: translateY(0); }
.term-prompt { color: var(--tok-cmt); }
.term-output { color: var(--ed-ok); font-weight: 600; }
.term-placeholder { color: var(--ed-muted); }
</style>
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">Button.ts</span>
</div>
<div class="code-body"><span class="tok-kw">interface</span> <span class="tok-type">Clickable</span> <span class="tok-punc">{</span>
<span class="tok-var">label</span><span class="tok-punc">:</span> <span class="tok-type">string</span><span class="tok-punc">;</span>
<span class="tok-var">onClick</span><span class="tok-punc">():</span> <span class="tok-type">void</span><span class="tok-punc">;</span>
<span class="tok-punc">}</span>
<span class="tok-kw">class</span> <span class="tok-type">Button</span> <span class="tok-kw">implements</span> <span class="tok-type">Clickable</span> <span class="tok-punc">{</span>
<span class="tok-var">label</span><span class="tok-punc">:</span> <span class="tok-type">string</span><span class="tok-punc">;</span>
<span class="tok-var">constructor</span><span class="tok-punc">(</span><span class="tok-var">label</span><span class="tok-punc">:</span> <span class="tok-type">string</span><span class="tok-punc">)</span> <span class="tok-punc">{</span>
<span class="tok-kw">this</span><span class="tok-punc">.</span><span class="tok-var">label</span> <span class="tok-punc">=</span> <span class="tok-var">label</span><span class="tok-punc">;</span>
<span class="tok-punc">}</span>
<span class="tok-var">onClick</span><span class="tok-punc">()</span> <span class="tok-punc">{</span>
<span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-var">log</span><span class="tok-punc">(</span><span class="tok-str">`${</span><span class="tok-kw">this</span><span class="tok-punc">.</span><span class="tok-var">label</span><span class="tok-str">} clicked!`</span><span class="tok-punc">);</span>
<span class="tok-punc">}</span>
<span class="tok-punc">}</span>
<span class="tok-kw">const</span> <span class="tok-var">btn</span> <span class="tok-punc">=</span> <span class="tok-kw">new</span> <span class="tok-var">Button</span><span class="tok-punc">(</span><span class="tok-str">"Submit"</span><span class="tok-punc">);</span></div>
</div>
<div class="output-frame">
<div class="output-bar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="output-label">output</span>
<span style="width:39px"></span>
</div>
<div class="output-screen">
<button class="demo-btn" id="demoBtn" type="button">Submit</button>
</div>
</div>
<div class="terminal">
<div class="output-bar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="output-label">console</span>
<span style="width:39px"></span>
</div>
<div class="term-body" id="termBody"><span class="term-line is-in term-placeholder">click the button above —</span></div>
</div>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-ts')
|| document.querySelector('.infographic-ts');
var root = wrapper;
var label = "Submit";
var btn = root.querySelector('#demoBtn');
var term = root.querySelector('#termBody');
var cleared = false;
btn.addEventListener('click', function () {
if (!cleared) {
term.innerHTML = '';
cleared = true;
}
var line = document.createElement('div');
line.className = 'term-line';
line.innerHTML = '<span class="term-prompt">></span> <span class="term-output">' + label + ' clicked!</span>';
term.appendChild(line);
requestAnimationFrame(function () { line.classList.add('is-in'); });
term.scrollTop = term.scrollHeight;
});
})();
</script>
</div>🚫 What You Can’t Do
You can’t implement a
typealias directly if it’s not a pure object shape (e.g., union or tuple).You must define all required members (no partial implementation allowed unless they're optional).
✅ Summary Table
Feature | Example |
|---|---|
Implement one |
|
Implement multiple |
|
Must match types | ✅ Required properties & methods |
Optional supported | ✅ |
Readonly respected | ✅ Must also be |