Chapter 10: TypeScript Type Aliases and Interfaces
TypeScript: Type Aliases vs Interfaces. This is like comparing two nearly identical tools that have subtle but important differences. Think of it like choosing between a Swiss Army knife and a specialized tool – sometimes you want versatility, sometimes you want precision.
I remember when I was learning TypeScript, I kept asking myself: “Should I use type or interface? They look the same! What’s the difference?” Let me save you that confusion by explaining everything from the ground up.
Part 1: First Encounters – What Are They?
Type Aliases
A type alias creates a name for any type. It’s like giving a nickname to a type:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<span class="token comment">// Basic primitive type</span> <span class="token keyword">type</span> <span class="token class-name">UserID</span> <span class="token operator">=</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token comment">// Object type</span> <span class="token class-name"><span class="token keyword">type</span></span> User <span class="token operator">=</span> <span class="token punctuation">{</span> id<span class="token operator">:</span> UserID<span class="token punctuation">;</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Function type</span> <span class="token class-name"><span class="token keyword">type</span></span> <span class="token function-variable function">UserCallback</span> <span class="token operator">=</span> <span class="token punctuation">(</span>user<span class="token operator">:</span> User<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token comment">// Union type</span> <span class="token class-name"><span class="token keyword">type</span></span> Status <span class="token operator">=</span> <span class="token string">"pending"</span> <span class="token operator">|</span> <span class="token string">"approved"</span> <span class="token operator">|</span> <span class="token string">"rejected"</span><span class="token punctuation">;</span> <span class="token comment">// Tuple type</span> <span class="token class-name"><span class="token keyword">type</span></span> Point <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// You can even do complex generics</span> <span class="token keyword">type</span> <span class="token class-name">Container<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span> timestamp<span class="token operator">:</span> Date<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
Interfaces
An interface specifically describes the shape of objects:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span><span class="token punctuation">;</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">UserWithRole</span> <span class="token keyword">extends</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> role<span class="token operator">:</span> <span class="token string">"admin"</span> <span class="token operator">|</span> <span class="token string">"editor"</span> <span class="token operator">|</span> <span class="token string">"viewer"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">UserCallbacks</span> <span class="token punctuation">{</span> <span class="token function-variable function">onSave</span><span class="token operator">:</span> <span class="token punctuation">(</span>user<span class="token operator">:</span> User<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function-variable function">onDelete</span><span class="token operator">:</span> <span class="token punctuation">(</span>userId<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token builtin">boolean</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
At first glance, they look almost identical. And for basic object types, they ARE identical:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="token comment">// These are essentially the same</span> <span class="token keyword">type</span> <span class="token class-name">UserType</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">UserInterface</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Both can be used the same way</span> <span class="token keyword">let</span> user1<span class="token operator">:</span> UserType <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">"Alice"</span><span class="token punctuation">,</span> age<span class="token operator">:</span> <span class="token number">30</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user2<span class="token operator">:</span> UserInterface <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> age<span class="token operator">:</span> <span class="token number">25</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
So why have both? Let’s dive deep.
Part 2: The Core Differences
Difference 1: What They Can Represent
This is the most fundamental difference. Interfaces can ONLY describe objects. Type aliases can describe ANYTHING.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="token comment">// ✅ Type alias can do ALL of these:</span> <span class="token keyword">type</span> <span class="token class-name">Primitive</span> <span class="token operator">=</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Union</span> <span class="token operator">=</span> <span class="token string">"active"</span> <span class="token operator">|</span> <span class="token string">"inactive"</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Tuple</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token builtin">boolean</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name"><span class="token builtin">Function</span></span> <span class="token operator">=</span> <span class="token punctuation">(</span>x<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Intersection</span> <span class="token operator">=</span> User <span class="token operator">&</span> <span class="token punctuation">{</span> permissions<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Mapped<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">K</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">K</span><span class="token punctuation">]</span> <span class="token operator">|</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// ❌ Interface can ONLY do this:</span> <span class="token keyword">interface</span> <span class="token class-name">Interface</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...that's it. Just objects.</span> |
Real-world implication: If you need unions, tuples, or primitive types, you MUST use type.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="token comment">// You HAVE to use type here:</span> <span class="token keyword">type</span> <span class="token class-name">APIResponse</span> <span class="token operator">=</span> <span class="token operator">|</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> <span class="token number">200</span><span class="token punctuation">;</span> data<span class="token operator">:</span> User <span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> <span class="token number">400</span><span class="token punctuation">;</span> error<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> <span class="token number">401</span><span class="token punctuation">;</span> error<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> <span class="token number">404</span><span class="token punctuation">;</span> error<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// This is NOT possible with interface</span> |
Difference 2: Declaration Merging
This is the superpower of interfaces that types don’t have. Interfaces can be reopened and extended.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="token comment">// First declaration</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Later in the same scope...</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token comment">// This gets merged!</span> phone<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token comment">// Also merged</span> <span class="token punctuation">}</span> <span class="token comment">// Now User has ALL three properties:</span> <span class="token keyword">let</span> user<span class="token operator">:</span> User <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">"Alice"</span><span class="token punctuation">,</span> email<span class="token operator">:</span> <span class="token string">"alice@example.com"</span><span class="token punctuation">,</span> age<span class="token operator">:</span> <span class="token number">30</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
Real-world example: This is incredibly useful when working with global objects or third-party libraries:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<span class="token comment">// Adding custom properties to Window</span> <span class="token keyword">interface</span> <span class="token class-name">Window</span> <span class="token punctuation">{</span> myCustomProperty<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> analytics<span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token function-variable function">track</span><span class="token operator">:</span> <span class="token punctuation">(</span>event<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">,</span> data<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">any</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Now this works!</span> window<span class="token punctuation">.</span>myCustomProperty <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span>analytics<span class="token punctuation">.</span><span class="token function">track</span><span class="token punctuation">(</span><span class="token string">"page_view"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> page<span class="token operator">:</span> <span class="token string">"/home"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Adding to Array</span> <span class="token keyword">interface</span> <span class="token class-name"><span class="token builtin">Array</span><span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token function">last</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token constant">T</span> <span class="token operator">|</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token function">first</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token constant">T</span> <span class="token operator">|</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Implementation</span> <span class="token builtin">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">last</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Now every array has .last()!</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">last</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> |
⚠️ Type aliases CANNOT do this:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token keyword">type</span> <span class="token class-name">User</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">User</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">// Error! Duplicate identifier 'User'</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
Difference 3: Extending/Inheriting
Both can extend other types, but they do it differently:
Interfaces use extends:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token keyword">interface</span> <span class="token class-name">BasicUser</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">AdminUser</span> <span class="token keyword">extends</span> <span class="token class-name">BasicUser</span> <span class="token punctuation">{</span> role<span class="token operator">:</span> <span class="token string">"admin"</span><span class="token punctuation">;</span> permissions<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">SuperAdmin</span> <span class="token keyword">extends</span> <span class="token class-name">AdminUser</span> <span class="token punctuation">{</span> canDeleteOthers<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Type aliases use intersections (&):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token keyword">type</span> <span class="token class-name">BasicUser</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">AdminUser</span> <span class="token operator">=</span> BasicUser <span class="token operator">&</span> <span class="token punctuation">{</span> role<span class="token operator">:</span> <span class="token string">"admin"</span><span class="token punctuation">;</span> permissions<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">SuperAdmin</span> <span class="token operator">=</span> AdminUser <span class="token operator">&</span> <span class="token punctuation">{</span> canDeleteOthers<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
Key difference: Interfaces are more declarative and produce better error messages. Intersections can be more flexible but sometimes behave unexpectedly with conflicting properties:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment">// Interface - TypeScript catches conflicts</span> <span class="token keyword">interface</span> <span class="token class-name"><span class="token constant">A</span></span> <span class="token punctuation">{</span> prop<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name"><span class="token constant">B</span></span> <span class="token punctuation">{</span> prop<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name"><span class="token constant">C</span></span> <span class="token keyword">extends</span> <span class="token class-name"><span class="token constant">A</span></span><span class="token punctuation">,</span> <span class="token constant">B</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">// Error! Property 'prop' has incompatible types</span> <span class="token comment">// Type alias - Creates 'never' (string & number is impossible)</span> <span class="token keyword">type</span> <span class="token class-name"><span class="token constant">A</span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> prop<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name"><span class="token constant">B</span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> prop<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name"><span class="token constant">C</span></span> <span class="token operator">=</span> <span class="token constant">A</span> <span class="token operator">&</span> <span class="token constant">B</span><span class="token punctuation">;</span> <span class="token comment">// prop is type 'never' - no error until you try to use it</span> |
Difference 4: Performance and Caching
Interfaces are cached – TypeScript can check them faster because they’re named and can be referenced by name.
Type aliases are evaluated – Each time you use a complex type alias, TypeScript might need to recompute it.
This rarely matters for small projects, but in large codebases, interfaces can be noticeably faster.
Part 3: Advanced Patterns – When Each Shines
Where Type Aliases Excel
1. Union Types
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="token comment">// This is only possible with type</span> <span class="token keyword">type</span> <span class="token class-name">Result<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token operator">|</span> <span class="token punctuation">{</span> success<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">;</span> data<span class="token operator">:</span> <span class="token constant">T</span> <span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span> success<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">;</span> error<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token generic-function"><span class="token function">fetchData</span><span class="token generic class-name"><span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> Result<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span> <span class="token punctuation">{</span> <span class="token comment">// implementation</span> <span class="token punctuation">}</span> |
2. Utility Types
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<span class="token comment">// Creating custom utility types</span> <span class="token keyword">type</span> <span class="token class-name">Nullable<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token operator">|</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Optional<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token operator">|</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Readonly<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">readonly</span> <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Partial<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Using mapped types</span> <span class="token keyword">type</span> <span class="token class-name">Getters<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">K</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span> <span class="token keyword">as</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">get</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>Capitalize<span class="token operator"><</span><span class="token builtin">string</span> <span class="token operator">&</span> <span class="token constant">K</span><span class="token operator">></span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">K</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">type</span> <span class="token class-name">UserGetters</span> <span class="token operator">=</span> Getters<span class="token operator"><</span>User<span class="token operator">></span><span class="token punctuation">;</span> <span class="token comment">// {</span> <span class="token comment">// getName: () => string;</span> <span class="token comment">// getAge: () => number;</span> <span class="token comment">// }</span> |
3. Tuple Types
|
0 1 2 3 4 5 6 7 8 |
<span class="token keyword">type</span> <span class="token class-name">Coordinate</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">CSVRow</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token builtin">boolean</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token builtin">any</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">HttpResponse</span> <span class="token operator">=</span> <span class="token punctuation">[</span>data<span class="token operator">:</span> <span class="token builtin">any</span><span class="token punctuation">,</span> status<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">,</span> headers<span class="token operator">:</span> Record<span class="token operator"><</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">string</span><span class="token operator">></span><span class="token punctuation">]</span><span class="token punctuation">;</span> |
4. Template Literal Types
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token keyword">type</span> <span class="token class-name">CSSUnit</span> <span class="token operator">=</span> <span class="token string">'px'</span> <span class="token operator">|</span> <span class="token string">'em'</span> <span class="token operator">|</span> <span class="token string">'rem'</span> <span class="token operator">|</span> <span class="token string">'%'</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">CSSSize</span> <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token builtin">number</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>CSSUnit<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">EventName<span class="token operator"><</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token builtin">string</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">T</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">Changed</span><span class="token template-punctuation string">`</span></span> <span class="token operator">|</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">T</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">Updated</span><span class="token template-punctuation string">`</span></span> <span class="token operator">|</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">T</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">Deleted</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">UserEvent</span> <span class="token operator">=</span> EventName<span class="token operator"><</span><span class="token string">'user'</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token comment">// "userChanged" | "userUpdated" | "userDeleted"</span> |
Where Interfaces Excel
1. Object-Oriented Design
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<span class="token keyword">interface</span> <span class="token class-name">Repository<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token function">findById</span><span class="token punctuation">(</span>id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token constant">T</span> <span class="token operator">|</span> <span class="token keyword">null</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token constant">T</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token function">create</span><span class="token punctuation">(</span>data<span class="token operator">:</span> Omit<span class="token operator"><</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">,</span> data<span class="token operator">:</span> Partial<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token keyword">delete</span><span class="token punctuation">(</span>id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token builtin">boolean</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">UserRepository</span> <span class="token keyword">implements</span> <span class="token class-name">Repository<span class="token operator"><</span>User<span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token comment">// Implementation must match interface exactly</span> <span class="token keyword">async</span> <span class="token function">findById</span><span class="token punctuation">(</span>id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span>User <span class="token operator">|</span> <span class="token keyword">null</span><span class="token operator">></span> <span class="token punctuation">{</span> <span class="token comment">// implementation</span> <span class="token punctuation">}</span> <span class="token comment">// ... other methods</span> <span class="token punctuation">}</span> |
2. Library/API Design
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<span class="token comment">// Public API - easier for users to extend</span> <span class="token keyword">export</span> <span class="token keyword">interface</span> <span class="token class-name">Plugin</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> version<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token function">setup</span><span class="token punctuation">(</span>app<span class="token operator">:</span> Application<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> teardown<span class="token operator">?</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Users can extend it</span> <span class="token keyword">declare</span> <span class="token keyword">module</span> <span class="token string">'my-library'</span> <span class="token punctuation">{</span> <span class="token keyword">interface</span> <span class="token class-name">Plugin</span> <span class="token punctuation">{</span> <span class="token comment">// Add their own properties</span> dependencies<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
3. Class Contracts
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="token keyword">interface</span> <span class="token class-name">Serializable</span> <span class="token punctuation">{</span> <span class="token function">serialize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">Deserializable<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token function">deserialize</span><span class="token punctuation">(</span>data<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">implements</span> <span class="token class-name">Serializable</span><span class="token punctuation">,</span> Deserializable<span class="token operator"><</span>User<span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token keyword">public</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token keyword">public</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token function">serialize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">string</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">deserialize</span><span class="token punctuation">(</span>data<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> User <span class="token punctuation">{</span> <span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>name<span class="token punctuation">,</span> obj<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
4. Hierarchical Type Systems
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<span class="token keyword">interface</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token function">makeSound</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">Mammal</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> furColor<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token function">giveBirth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">Dog</span> <span class="token keyword">extends</span> <span class="token class-name">Mammal</span> <span class="token punctuation">{</span> breed<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Clear inheritance chain</span> <span class="token keyword">function</span> <span class="token function">processDog</span><span class="token punctuation">(</span>dog<span class="token operator">:</span> Dog<span class="token punctuation">)</span> <span class="token punctuation">{</span> dog<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token comment">// from Animal</span> dog<span class="token punctuation">.</span>furColor<span class="token punctuation">;</span> <span class="token comment">// from Mammal</span> dog<span class="token punctuation">.</span>breed<span class="token punctuation">;</span> <span class="token comment">// from Dog</span> <span class="token punctuation">}</span> |
Part 4: Real-World Case Study – Building a Form System
Let’s build a complete form validation system to see how types and interfaces work together:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
<span class="token comment">// ============================================</span> <span class="token comment">// PART 1: Type Aliases - For flexible, composable types</span> <span class="token comment">// ============================================</span> <span class="token comment">// Primitive types and unions - MUST use type</span> <span class="token class-name"><span class="token keyword">type</span></span> FormValue <span class="token operator">=</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span> <span class="token operator">|</span> <span class="token builtin">boolean</span> <span class="token operator">|</span> <span class="token keyword">null</span> <span class="token operator">|</span> File <span class="token operator">|</span> Date<span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">ValidationResult</span> <span class="token operator">=</span> <span class="token operator">|</span> <span class="token punctuation">{</span> valid<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span> valid<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">;</span> error<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Utility types - BEST with type</span> <span class="token class-name"><span class="token keyword">type</span></span> Validator<span class="token operator"><</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">FormValue</span> <span class="token operator">=</span> FormValue<span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">(</span>value<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">)</span> <span class="token operator">=></span> ValidationResult<span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">AsyncValidator<span class="token operator"><</span><span class="token constant">T</span> <span class="token keyword">extends</span> FormValue <span class="token operator">=</span> FormValue<span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">(</span>value<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">Promise</span><span class="token operator"><</span>ValidationResult<span class="token operator">></span><span class="token punctuation">;</span> <span class="token comment">// Tuple types - MUST use type</span> <span class="token class-name"><span class="token keyword">type</span></span> FieldConfig<span class="token operator"><</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">FormValue</span> <span class="token operator">=</span> FormValue<span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">[</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">,</span> initialValue<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">,</span> validators<span class="token operator">?</span><span class="token operator">:</span> Validator<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> asyncValidators<span class="token operator">?</span><span class="token operator">:</span> AsyncValidator<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// Complex mapped types - BEST with type</span> <span class="token class-name"><span class="token keyword">type</span></span> FormErrors<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">K</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">FormTouched<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">K</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Template literal types - ONLY with type</span> <span class="token class-name"><span class="token keyword">type</span></span> FormEvent<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span> <span class="token operator">=</span> <span class="token operator">|</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">field:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token builtin">string</span> <span class="token operator">&</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:change</span><span class="token template-punctuation string">`</span></span> <span class="token operator">|</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">field:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token builtin">string</span> <span class="token operator">&</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:blur</span><span class="token template-punctuation string">`</span></span> <span class="token operator">|</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">field:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token builtin">string</span> <span class="token operator">&</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:focus</span><span class="token template-punctuation string">`</span></span> <span class="token operator">|</span> <span class="token string">'form:submit'</span> <span class="token operator">|</span> <span class="token string">'form:reset'</span> <span class="token operator">|</span> <span class="token string">'form:validate'</span><span class="token punctuation">;</span> <span class="token comment">// ============================================</span> <span class="token comment">// PART 2: Interfaces - For object shapes and OOP</span> <span class="token comment">// ============================================</span> <span class="token comment">// Core domain interfaces</span> <span class="token keyword">interface</span> <span class="token class-name">Field<span class="token operator"><</span><span class="token constant">T</span> <span class="token keyword">extends</span> FormValue <span class="token operator">=</span> FormValue<span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token keyword">readonly</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> value<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span> <span class="token keyword">readonly</span> initialValue<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span> errors<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> touched<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> dirty<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> valid<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> validating<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> <span class="token function">setValue</span><span class="token punctuation">(</span>value<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function">setErrors</span><span class="token punctuation">(</span>errors<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function">setTouched</span><span class="token punctuation">(</span>touched<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span>ValidationResult<span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">Form<span class="token operator"><</span><span class="token constant">T</span> <span class="token keyword">extends</span> Record<span class="token operator"><</span><span class="token builtin">string</span><span class="token punctuation">,</span> FormValue<span class="token operator">></span> <span class="token operator">=</span> Record<span class="token operator"><</span><span class="token builtin">string</span><span class="token punctuation">,</span> FormValue<span class="token operator">>></span></span> <span class="token punctuation">{</span> <span class="token keyword">readonly</span> id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> values<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span> errors<span class="token operator">:</span> FormErrors<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">;</span> touched<span class="token operator">:</span> FormTouched<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">;</span> dirty<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> valid<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> submitting<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> submitted<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span> <span class="token generic-function"><span class="token function">setFieldValue</span><span class="token generic class-name"><span class="token operator"><</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>name<span class="token operator">:</span> <span class="token constant">K</span><span class="token punctuation">,</span> value<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">K</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token generic-function"><span class="token function">setFieldError</span><span class="token generic class-name"><span class="token operator"><</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>name<span class="token operator">:</span> <span class="token constant">K</span><span class="token punctuation">,</span> error<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token generic-function"><span class="token function">setFieldTouched</span><span class="token generic class-name"><span class="token operator"><</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>name<span class="token operator">:</span> <span class="token constant">K</span><span class="token punctuation">,</span> touched<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token builtin">boolean</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token function">submit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token keyword">void</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Plugin system using interface merging</span> <span class="token keyword">interface</span> <span class="token class-name">FormPlugin</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token function">setup</span><span class="token punctuation">(</span>form<span class="token operator">:</span> Form<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> teardown<span class="token operator">?</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Allow plugins to extend Form interface</span> <span class="token class-name"><span class="token keyword">declare</span></span> <span class="token keyword">module</span> <span class="token string">'./form'</span> <span class="token punctuation">{</span> <span class="token keyword">interface</span> <span class="token class-name">Form</span> <span class="token punctuation">{</span> plugins<span class="token operator">:</span> Map<span class="token operator"><</span><span class="token builtin">string</span><span class="token punctuation">,</span> FormPlugin<span class="token operator">></span><span class="token punctuation">;</span> <span class="token function">use</span><span class="token punctuation">(</span>plugin<span class="token operator">:</span> FormPlugin<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// ============================================</span> <span class="token comment">// PART 3: Implementation - Using both together</span> <span class="token comment">// ============================================</span> <span class="token comment">// Validators using type aliases</span> <span class="token keyword">const</span> required<span class="token operator">:</span> <span class="token function-variable function">Validator</span> <span class="token operator">=</span> <span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> valid<span class="token operator">:</span> value <span class="token operator">!==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> value <span class="token operator">!==</span> <span class="token keyword">undefined</span> <span class="token operator">&&</span> value <span class="token operator">!==</span> <span class="token string">''</span><span class="token punctuation">,</span> error<span class="token operator">:</span> <span class="token string">'This field is required'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> minLength <span class="token operator">=</span> <span class="token punctuation">(</span>length<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">)</span><span class="token operator">:</span> Validator<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span> <span class="token operator">=></span> <span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> valid<span class="token operator">:</span> value<span class="token punctuation">.</span>length <span class="token operator">>=</span> length<span class="token punctuation">,</span> error<span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Must be at least </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>length<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> characters</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> maxLength <span class="token operator">=</span> <span class="token punctuation">(</span>length<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">)</span><span class="token operator">:</span> Validator<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span> <span class="token operator">=></span> <span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> valid<span class="token operator">:</span> value<span class="token punctuation">.</span><span class="token generic-function"><span class="token function">length</span> <span class="token generic class-name"><span class="token operator"><=</span> length<span class="token punctuation">,</span></span></span> error<span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Must be no more than </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>length<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> characters</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> email<span class="token operator">:</span> Validator<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> valid<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[^\s@]+@[^\s@]+\.[^\s@]+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">,</span> error<span class="token operator">:</span> <span class="token string">'Invalid email format'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Async validator example</span> <span class="token keyword">const</span> uniqueUsername<span class="token operator">:</span> AsyncValidator<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/api/check-username?username=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>value<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> isAvailable <span class="token operator">=</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> valid<span class="token operator">:</span> isAvailable<span class="token punctuation">,</span> error<span class="token operator">:</span> <span class="token string">'Username already taken'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Concrete field implementation</span> <span class="token keyword">class</span> <span class="token class-name">TextField</span> <span class="token keyword">implements</span> <span class="token class-name">Field<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token keyword">readonly</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token keyword">readonly</span> initialValue<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> value<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> errors<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> touched<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> dirty<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> valid<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> validating<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">private</span> validators<span class="token operator">:</span> Validator<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">private</span> asyncValidators<span class="token operator">:</span> AsyncValidator<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">constructor</span><span class="token punctuation">(</span>config<span class="token operator">:</span> FieldConfig<span class="token operator"><</span><span class="token builtin">string</span><span class="token operator">></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> initialValue<span class="token punctuation">,</span> validators <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> asyncValidators <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> config<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>initialValue <span class="token operator">=</span> initialValue<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> initialValue<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>validators <span class="token operator">=</span> validators<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>asyncValidators <span class="token operator">=</span> asyncValidators<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">setValue</span><span class="token punctuation">(</span>value<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dirty <span class="token operator">=</span> value <span class="token operator">!==</span> <span class="token keyword">this</span><span class="token punctuation">.</span>initialValue<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">setErrors</span><span class="token punctuation">(</span>errors<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>errors <span class="token operator">=</span> errors<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>valid <span class="token operator">=</span> errors<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">setTouched</span><span class="token punctuation">(</span>touched<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>touched <span class="token operator">=</span> touched<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>touched<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>initialValue<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>errors <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>touched <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dirty <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>valid <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>validating <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">async</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span>ValidationResult<span class="token operator">></span> <span class="token punctuation">{</span> <span class="token comment">// Synchronous validation</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> validator <span class="token keyword">of</span> <span class="token keyword">this</span><span class="token punctuation">.</span>validators<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token function">validator</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>result<span class="token punctuation">.</span>valid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setErrors</span><span class="token punctuation">(</span><span class="token punctuation">[</span>result<span class="token punctuation">.</span>error<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Async validation</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>asyncValidators<span class="token punctuation">.</span>length <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>validating <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> validator <span class="token keyword">of</span> <span class="token keyword">this</span><span class="token punctuation">.</span>asyncValidators<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">validator</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>result<span class="token punctuation">.</span>valid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setErrors</span><span class="token punctuation">(</span><span class="token punctuation">[</span>result<span class="token punctuation">.</span>error<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>validating <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">return</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setErrors</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'Validation failed'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>validating <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> valid<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> error<span class="token operator">:</span> <span class="token string">'Validation failed'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span>validating <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setErrors</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> valid<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Form implementation</span> <span class="token keyword">class</span> <span class="token class-name">UserRegistrationForm</span> <span class="token keyword">implements</span> <span class="token class-name">Form<span class="token operator"><</span>UserRegistration<span class="token operator">></span></span> <span class="token punctuation">{</span> id <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">36</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">;</span> values<span class="token operator">:</span> UserRegistration<span class="token punctuation">;</span> errors<span class="token operator">:</span> FormErrors<span class="token operator"><</span>UserRegistration<span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> touched<span class="token operator">:</span> FormTouched<span class="token operator"><</span>UserRegistration<span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> dirty<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> valid<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> submitting<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> submitted<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> plugins<span class="token operator">:</span> Map<span class="token operator"><</span><span class="token builtin">string</span><span class="token punctuation">,</span> FormPlugin<span class="token operator">></span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">private</span> fields<span class="token operator">:</span> Map<span class="token operator"><</span><span class="token keyword">keyof</span> UserRegistration<span class="token punctuation">,</span> Field<span class="token operator">></span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Initialize fields using tuple configs</span> <span class="token keyword">const</span> usernameField <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TextField</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token string">'username'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>required<span class="token punctuation">,</span> <span class="token function">minLength</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">maxLength</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>uniqueUsername<span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> emailField <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TextField</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token string">'email'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>required<span class="token punctuation">,</span> email<span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> passwordField <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TextField</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token string">'password'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>required<span class="token punctuation">,</span> <span class="token function">minLength</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'username'</span><span class="token punctuation">,</span> usernameField<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'email'</span><span class="token punctuation">,</span> emailField<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'password'</span><span class="token punctuation">,</span> passwordField<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>values <span class="token operator">=</span> <span class="token punctuation">{</span> username<span class="token operator">:</span> usernameField<span class="token punctuation">.</span>value<span class="token punctuation">,</span> email<span class="token operator">:</span> emailField<span class="token punctuation">.</span>value<span class="token punctuation">,</span> password<span class="token operator">:</span> passwordField<span class="token punctuation">.</span>value <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token generic-function"><span class="token function">setFieldValue</span><span class="token generic class-name"><span class="token operator"><</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token keyword">keyof</span> UserRegistration<span class="token operator">></span></span></span><span class="token punctuation">(</span>name<span class="token operator">:</span> <span class="token constant">K</span><span class="token punctuation">,</span> value<span class="token operator">:</span> UserRegistration<span class="token punctuation">[</span><span class="token constant">K</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> field <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>field<span class="token punctuation">)</span> <span class="token punctuation">{</span> field<span class="token punctuation">.</span><span class="token function">setValue</span><span class="token punctuation">(</span>value <span class="token keyword">as</span> <span class="token builtin">any</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>values<span class="token punctuation">[</span>name<span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dirty <span class="token operator">=</span> <span class="token builtin">Array</span><span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">some</span><span class="token punctuation">(</span>f <span class="token operator">=></span> f<span class="token punctuation">.</span>dirty<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token generic-function"><span class="token function">setFieldError</span><span class="token generic class-name"><span class="token operator"><</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token keyword">keyof</span> UserRegistration<span class="token operator">></span></span></span><span class="token punctuation">(</span>name<span class="token operator">:</span> <span class="token constant">K</span><span class="token punctuation">,</span> error<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>errors<span class="token punctuation">[</span>name<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>error<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> field <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>field<span class="token punctuation">)</span> <span class="token punctuation">{</span> field<span class="token punctuation">.</span><span class="token function">setErrors</span><span class="token punctuation">(</span><span class="token punctuation">[</span>error<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token generic-function"><span class="token function">setFieldTouched</span><span class="token generic class-name"><span class="token operator"><</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token keyword">keyof</span> UserRegistration<span class="token operator">></span></span></span><span class="token punctuation">(</span>name<span class="token operator">:</span> <span class="token constant">K</span><span class="token punctuation">,</span> touched<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>touched<span class="token punctuation">[</span>name<span class="token punctuation">]</span> <span class="token operator">=</span> touched<span class="token punctuation">;</span> <span class="token keyword">const</span> field <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>field<span class="token punctuation">)</span> <span class="token punctuation">{</span> field<span class="token punctuation">.</span><span class="token function">setTouched</span><span class="token punctuation">(</span>touched<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">async</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token builtin">boolean</span><span class="token operator">></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> validationPromises <span class="token operator">=</span> <span class="token builtin">Array</span><span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">[</span>name<span class="token punctuation">,</span> field<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token keyword">await</span> field<span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>result<span class="token punctuation">.</span>valid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>errors<span class="token punctuation">[</span>name<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>result<span class="token punctuation">.</span>error<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">delete</span> <span class="token keyword">this</span><span class="token punctuation">.</span>errors<span class="token punctuation">[</span>name<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">await</span> <span class="token builtin">Promise</span><span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>validationPromises<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>valid <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>errors<span class="token punctuation">)</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>valid<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">async</span> <span class="token function">submit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token keyword">void</span><span class="token operator">></span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>submitting <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> isValid <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>isValid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">'Form validation failed'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Emit form:submit event</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">'form:submit'</span> <span class="token keyword">as</span> FormEvent<span class="token operator"><</span>UserRegistration<span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Simulate API call</span> <span class="token keyword">await</span> <span class="token keyword">new</span> <span class="token class-name"><span class="token builtin">Promise</span></span><span class="token punctuation">(</span>resolve <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>submitted <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Form submitted:'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>values<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">'Submission failed:'</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">throw</span> error<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>submitting <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>field <span class="token operator">=></span> field<span class="token punctuation">.</span><span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>values <span class="token operator">=</span> <span class="token punctuation">{</span> username<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'username'</span><span class="token punctuation">)</span><span class="token operator">?.</span>value <span class="token keyword">as</span> <span class="token builtin">string</span><span class="token punctuation">,</span> email<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'email'</span><span class="token punctuation">)</span><span class="token operator">?.</span>value <span class="token keyword">as</span> <span class="token builtin">string</span><span class="token punctuation">,</span> password<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fields<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'password'</span><span class="token punctuation">)</span><span class="token operator">?.</span>value <span class="token keyword">as</span> <span class="token builtin">string</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>errors <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>touched <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dirty <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>valid <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>submitting <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>submitted <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">use</span><span class="token punctuation">(</span>plugin<span class="token operator">:</span> FormPlugin<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>plugins<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>plugin<span class="token punctuation">.</span>name<span class="token punctuation">,</span> plugin<span class="token punctuation">)</span><span class="token punctuation">;</span> plugin<span class="token punctuation">.</span><span class="token function">setup</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token function">emit</span><span class="token punctuation">(</span>event<span class="token operator">:</span> FormEvent<span class="token operator"><</span>UserRegistration<span class="token operator">></span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// Event emission logic</span> <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Event emitted: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>event<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// ============================================</span> <span class="token comment">// PART 4: Usage - The beautiful result</span> <span class="token comment">// ============================================</span> <span class="token keyword">interface</span> <span class="token class-name">UserRegistration</span> <span class="token punctuation">{</span> username<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> password<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Create form</span> <span class="token keyword">const</span> form <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UserRegistrationForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Add a plugin using interface merging</span> form<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'logger'</span><span class="token punctuation">,</span> <span class="token function">setup</span><span class="token punctuation">(</span>form<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Form </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>form<span class="token punctuation">.</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> initialized</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Can access form properties safely</span> form<span class="token punctuation">.</span>values<span class="token punctuation">;</span> <span class="token comment">// TypeScript knows this is UserRegistration</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">teardown</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Logger plugin removed'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Interact with form</span> form<span class="token punctuation">.</span><span class="token function">setFieldValue</span><span class="token punctuation">(</span><span class="token string">'username'</span><span class="token punctuation">,</span> <span class="token string">'john_doe'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> form<span class="token punctuation">.</span><span class="token function">setFieldTouched</span><span class="token punctuation">(</span><span class="token string">'username'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> form<span class="token punctuation">.</span><span class="token function">setFieldValue</span><span class="token punctuation">(</span><span class="token string">'email'</span><span class="token punctuation">,</span> <span class="token string">'john@example.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> form<span class="token punctuation">.</span><span class="token function">setFieldValue</span><span class="token punctuation">(</span><span class="token string">'password'</span><span class="token punctuation">,</span> <span class="token string">'secure123'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Check validation</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> isValid <span class="token operator">=</span> <span class="token keyword">await</span> form<span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Form valid:'</span><span class="token punctuation">,</span> isValid<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Errors:'</span><span class="token punctuation">,</span> form<span class="token punctuation">.</span>errors<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>isValid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">await</span> form<span class="token punctuation">.</span><span class="token function">submit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Part 5: The Great Debate – When to Use What?
After years of TypeScript development, here’s my practical guide:
✅ USE INTERFACE WHEN:
1. You’re defining the shape of objects (especially in public APIs)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="token comment">// Library code - users might extend it</span> <span class="token keyword">export</span> <span class="token keyword">interface</span> <span class="token class-name">Config</span> <span class="token punctuation">{</span> apiUrl<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> timeout<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> retries<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">interface</span> <span class="token class-name">Plugin</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token function">setup</span><span class="token punctuation">(</span>config<span class="token operator">:</span> Config<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
2. You’re working with classes (implements)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="token keyword">interface</span> <span class="token class-name">IRepository<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token function">find</span><span class="token punctuation">(</span>id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token function">save</span><span class="token punctuation">(</span>item<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">UserRepository</span> <span class="token keyword">implements</span> <span class="token class-name">IRepository<span class="token operator"><</span>User<span class="token operator">></span></span> <span class="token punctuation">{</span> <span class="token comment">// Clear contract enforcement</span> <span class="token punctuation">}</span> |
3. You need declaration merging
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token comment">// Augmenting Express Request</span> <span class="token keyword">declare</span> <span class="token keyword">namespace</span> Express <span class="token punctuation">{</span> <span class="token keyword">interface</span> <span class="token class-name">Request</span> <span class="token punctuation">{</span> user<span class="token operator">?</span><span class="token operator">:</span> User<span class="token punctuation">;</span> session<span class="token operator">:</span> Session<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
4. You want better error messages and performance
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="token comment">// Interface errors are often clearer</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token comment">// Error: Should be number</span> <span class="token punctuation">}</span> <span class="token comment">// vs</span> <span class="token keyword">type</span> <span class="token class-name">User</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token comment">// Error message might be more complex</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
✅ USE TYPE WHEN:
1. You need unions or intersections
|
0 1 2 3 4 5 6 7 8 |
<span class="token keyword">type</span> <span class="token class-name"><span class="token constant">ID</span></span> <span class="token operator">=</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Status</span> <span class="token operator">=</span> <span class="token string">'pending'</span> <span class="token operator">|</span> <span class="token string">'approved'</span> <span class="token operator">|</span> <span class="token string">'rejected'</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">Response<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> Success<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span> <span class="token operator">|</span> Failure<span class="token punctuation">;</span> |
2. You’re using tuples
|
0 1 2 3 4 5 6 7 |
<span class="token keyword">type</span> <span class="token class-name">Point</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">CSVRow</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token builtin">any</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> |
3. You need mapped types or conditional types
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token keyword">type</span> <span class="token class-name">Nullable<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span> <span class="token operator">|</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">FunctionPropertyNames<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">K</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">K</span><span class="token punctuation">]</span> <span class="token keyword">extends</span> <span class="token class-name"><span class="token builtin">Function</span></span> <span class="token operator">?</span> <span class="token constant">K</span> <span class="token operator">:</span> <span class="token builtin">never</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token punctuation">;</span> |
4. You’re creating utility types
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token keyword">type</span> <span class="token class-name">DeepReadonly<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">readonly</span> <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span> DeepReadonly<span class="token operator"><</span><span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">AsyncFunction<span class="token operator"><</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">R</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">(</span>arg<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">Promise</span><span class="token operator"><</span><span class="token constant">R</span><span class="token operator">></span><span class="token punctuation">;</span> |
5. You need computed properties
|
0 1 2 3 4 5 6 7 8 |
<span class="token keyword">type</span> <span class="token class-name">PropType<span class="token operator"><</span>TObj<span class="token punctuation">,</span> TProp <span class="token keyword">extends</span> <span class="token keyword">keyof</span> TObj<span class="token operator">></span></span> <span class="token operator">=</span> TObj<span class="token punctuation">[</span>TProp<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">UserProp</span> <span class="token operator">=</span> PropType<span class="token operator"><</span>User<span class="token punctuation">,</span> <span class="token string">'name'</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token comment">// string</span> |
Part 6: The “Both” Approach – Best of Both Worlds
Sometimes the best solution is to use both:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<span class="token comment">// Define the core shape with interface</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> createdAt<span class="token operator">:</span> Date<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Create utility types from the interface</span> <span class="token class-name"><span class="token keyword">type</span></span> UserWithoutId <span class="token operator">=</span> Omit<span class="token operator"><</span>User<span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">UserWithRole</span> <span class="token operator">=</span> User <span class="token operator">&</span> <span class="token punctuation">{</span> role<span class="token operator">:</span> <span class="token string">'admin'</span> <span class="token operator">|</span> <span class="token string">'user'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">type</span> <span class="token class-name">UserUpdatePayload</span> <span class="token operator">=</span> Partial<span class="token operator"><</span>UserWithoutId<span class="token operator">></span><span class="token punctuation">;</span> <span class="token comment">// Create unions with the interface</span> <span class="token class-name"><span class="token keyword">type</span></span> APIUserResponse <span class="token operator">=</span> <span class="token operator">|</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> <span class="token number">200</span><span class="token punctuation">;</span> data<span class="token operator">:</span> User <span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> <span class="token number">404</span><span class="token punctuation">;</span> error<span class="token operator">:</span> <span class="token string">'User not found'</span> <span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> <span class="token number">500</span><span class="token punctuation">;</span> error<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Extend the interface with declaration merging</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token comment">// Add methods (using type for the function signature)</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> ValidationResult<span class="token punctuation">;</span> <span class="token function">toJSON</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> UserWithoutId<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Implement the interface</span> <span class="token class-name"><span class="token keyword">class</span></span> RegularUser <span class="token keyword">implements</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token comment">// ... implementation</span> <span class="token punctuation">}</span> |
This pattern is incredibly powerful:
-
Interface provides the contract, OOP capabilities, and extensibility
-
Type provides the flexibility for unions, utilities, and complex transformations
Part 7: Common Pitfalls and How to Avoid Them
Pitfall 1: Using Type When You Need Declaration Merging
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment">// ❌ This won't work for extending global types</span> <span class="token keyword">type</span> <span class="token class-name">Window</span> <span class="token punctuation">{</span> myProperty<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Error!</span> <span class="token comment">// ✅ Use interface for augmentation</span> <span class="token keyword">interface</span> <span class="token class-name">Window</span> <span class="token punctuation">{</span> myProperty<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Works!</span> |
Pitfall 2: Using Interface for Union Types
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token comment">// ❌ This doesn't work</span> <span class="token keyword">interface</span> <span class="token class-name">Status</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token string">'pending'</span> <span class="token operator">|</span> <span class="token string">'approved'</span> <span class="token operator">|</span> <span class="token string">'rejected'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Not a union type!</span> <span class="token comment">// ✅ Use type</span> <span class="token class-name"><span class="token keyword">type</span></span> Status <span class="token operator">=</span> <span class="token string">'pending'</span> <span class="token operator">|</span> <span class="token string">'approved'</span> <span class="token operator">|</span> <span class="token string">'rejected'</span><span class="token punctuation">;</span> |
Pitfall 3: Overusing Type for Object Shapes
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="token comment">// ❌ This works but loses extensibility</span> <span class="token keyword">type</span> <span class="token class-name">User</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Later, you can't add properties through declaration merging</span> <span class="token comment">// No way to do this with type:</span> <span class="token comment">// type User = { email: string; } // Error!</span> <span class="token comment">// ✅ Use interface for objects that might be extended</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Later:</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ✓ Works!</span> |
Pitfall 4: Confusing “implements” with Type Aliases
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="token comment">// This works, but it's not ideal</span> <span class="token keyword">type</span> <span class="token class-name">UserType</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">implements</span> <span class="token class-name">UserType</span> <span class="token punctuation">{</span> <span class="token comment">// ✓ This works</span> name<span class="token operator">:</span> <span class="token builtin">string</span> <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// But you can't implement union types</span> <span class="token keyword">type</span> <span class="token class-name"><span class="token constant">ID</span></span> <span class="token operator">=</span> <span class="token builtin">string</span> <span class="token operator">|</span> <span class="token builtin">number</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">Item</span> <span class="token keyword">implements</span> <span class="token class-name"><span class="token constant">ID</span></span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">// Error! Cannot implement union type</span> |
Part 8: Performance Considerations
In large codebases, these differences matter:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<span class="token comment">// Interface - cached, faster to check</span> <span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> address<span class="token operator">:</span> <span class="token punctuation">{</span> street<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> city<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> country<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Type - recomputed each time, potentially slower</span> <span class="token keyword">type</span> <span class="token class-name">User</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> age<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> address<span class="token operator">:</span> <span class="token punctuation">{</span> street<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> city<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> country<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Complex type alias - expensive to compute repeatedly</span> <span class="token keyword">type</span> <span class="token class-name">DeepPartial<span class="token operator"><</span><span class="token constant">T</span><span class="token operator">></span></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> <span class="token keyword">keyof</span> <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span> <span class="token keyword">extends</span> <span class="token class-name">object</span> <span class="token operator">?</span> DeepPartial<span class="token operator"><</span><span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span><span class="token operator">></span> <span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Better: Create a named type</span> <span class="token class-name"><span class="token keyword">type</span></span> PartialUser <span class="token operator">=</span> DeepPartial<span class="token operator"><</span>User<span class="token operator">></span><span class="token punctuation">;</span> <span class="token comment">// Then reuse PartialUser instead of recalculating DeepPartial<User></span> |
Part 9: Decision Tree – Your Practical Guide
Here’s the decision tree I use when teaching this:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
START HERE | v Is it describing the SHAPE OF AN OBJECT? | +-- YES --> Do you need DECLARATION MERGING? | (augmenting, extending in multiple places) | | | +-- YES --> USE INTERFACE | | | +-- NO --> Are you writing a PUBLIC API/LIBRARY? | (might be extended by users) | | | +-- YES --> USE INTERFACE | | | +-- NO --> Do you prefer OOP style? | (classes, extends, implements) | | | +-- YES --> USE INTERFACE | | | +-- NO --> Either works, I'd choose INTERFACE | +-- NO --> Is it a UNION, TUPLE, PRIMITIVE, or COMPLEX GENERIC? (anything that isn't a simple object) | +-- YES --> USE TYPE ALIAS | +-- NO --> Is it a FUNCTION TYPE? | +-- YES --> USE TYPE ALIAS | +-- NO --> Is it a UTILITY/MAPPED TYPE? | +-- YES --> USE TYPE ALIAS | +-- NO --> USE INTERFACE (default) |
Part 10: My Personal Philosophy
After years of TypeScript, here’s what I’ve settled on:
-
Default to
interfacefor objects – It’s more declarative, faster, and more extensible -
Use
typefor everything else – Unions, tuples, primitives, utilities -
Never fight the tool – If you need declaration merging, use
interface. If you need unions, usetype. -
Be consistent – Pick a pattern and stick with it in your codebase
-
Document your choice – If you have a team, agree on guidelines
My actual daily rule:
-
95% of the time:
interfacefor objects,typefor everything else -
5% of the time: Whatever makes the code cleaner and more maintainable
Summary: The Big Picture
TypeScript gives us two ways to name types, and they’re both valuable:
Interfaces are about contracts and extension. They’re perfect for:
-
Public APIs
-
Object-oriented designs
-
Systems that need to be extended
-
Global type augmentation
Type aliases are about flexibility and composition. They’re perfect for:
-
Unions and intersections
-
Complex generic transformations
-
Tuples and primitives
-
One-off utility types
The beautiful thing is that TypeScript doesn’t force you to choose. Use both! Let them play to their strengths. Your code will be more expressive, more maintainable, and more type-safe as a result.
Remember: This isn’t about which one is “better” – it’s about which tool is right for the job. A carpenter doesn’t ask “are hammers better than saws?” They ask “am I driving a nail or cutting wood?”
Now go forth and type with confidence! 🚀
Does this help clarify the relationship between type aliases and interfaces? Would you like me to elaborate on any specific aspect or show more examples of when to use each?
