TypeScript Interfaces
From SCRUM-7 and SCRUM-18: Define TypeScript interfaces
My Learning Notes
Object Types can be defined with
{},type, orinterface. With interface, subtypes can be created from other types usingextend. One subtype can inherit props from multiple parents, so the amount of boilerplate code is cut down.
Key Insights from Code Review
- Always use lowercase primitive types (
string, notString) - Add
exportkeyword from the start when creating shared types - Double-check field names against specs (typos happen!)
What is an Interface?
An interface defines the shape of an object - what properties it has and their types.
interface Word {
id: string;
word: string;
definition: string;
userId: string;
categoryId?: string; // Optional property
createdAt: Date;
updatedAt: Date;
}
Interface vs Type
Both can define object shapes, but they handle conflicts differently:
Using extends (Interface)
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
// Can extend multiple interfaces
interface Pet extends Animal, Nameable {
owner: string;
}
Using Intersection & (Type)
type Animal = { name: string };
type Dog = Animal & { breed: string };
extendsshows conflicts as errors (safer!)- Intersection
&can lead tonevertype if conflicts arise
Optional Properties
Use ? to mark optional properties. You can also assign default values:
interface Category {
id: string;
name: string;
color: string;
description?: string; // Optional
}
// Usage with default
function createCategory(input: CategoryInput) {
return {
...input,
description: input.description ?? "No description"
};
}
Union Types
When a field can be more than one type, use |:
interface ApiResponse {
status: "success" | "error";
data: Word | null;
code: number | string;
}
Readonly Properties
Use readonly for properties that shouldn't change:
interface User {
readonly id: string; // Can't be changed after creation
name: string; // Can be changed
}
VocabPal Interfaces
Our project uses these key interfaces (from SCRUM-7):
// Word saved by user
interface Word {
id: string;
word: string;
definition: string;
userId: string;
categoryId?: string;
createdAt: Date;
updatedAt: Date;
}
// Category for organizing words
interface Category {
id: string;
name: string;
color: string;
userId: string;
createdAt: Date;
updatedAt: Date;
}
// Input types (for creating new items)
type WordInput = Omit<Word, 'id' | 'createdAt' | 'updatedAt'>;
type CategoryInput = Omit<Category, 'id' | 'createdAt' | 'updatedAt'>;
Modeling API Responses
When working with external APIs, create separate interfaces for nested data:
// Dictionary API response structure
interface Phonetics {
text?: string; // Optional - not always present
audio?: string;
}
interface Definition {
definition: string;
example?: string; // Optional
}
interface Meaning {
partOfSpeech: string;
definitions: Definition[];
}
interface DictionaryApiResponse {
word: string;
phonetics: Phonetics[];
meanings: Meaning[];
}
When working with external APIs, test with a real API call to check which fields are actually optional vs required!
Notes from SCRUM-18
Synced from Jira on 2026-04-04
- Interface vs Type, extending Interfaces: Object Types can be defined with {}, type or interface. With interface, subtypes can be created from other types using “extend”. 1 subtypes can inherit props from multiple parents, so amount of boilerplate code is cut down.
- Additionally, combination of types can be made using intersection(&). Different to extend when handling conflict of types. Extended type will flag conflict as error while intersection force to satisfy all types definitions if conflict arises, and can lead to “never” type.
- Optional properties: when the field can be optional in creating an instance of a typescript object. Mark with “?”. We can assign a default value for that optional properties as well.
- Union types: when 1 field can be more than 1 type, marked with “|”. For example: number|string
Code Review Feedback
Katie Nguyen (2026-02-02):
[Code Review Feedback]
Great job documenting your learning! Your notes demonstrate solid understanding of the core concepts. You correctly identified that extends shows conflicts as errors while intersection can lead to never type - this is an important distinction. Good understanding of optional properties and union types too.
Tip: When you use interfaces in real code, remember to add the export keyword so other files can import them!
Key Takeaways
- Use
interfacefor object shapes (can extend) - Use
typefor unions and complex types extendscatches conflicts;&may createnever- Mark optional fields with
? - Always
exportshared interfaces - Test APIs to know which fields are optional