This reference covers all TypeScript types, interfaces, enums, and patterns used in the ML Store project.
Basic Types
Type Description Example stringText values const name: string = "John"numberNumeric values (int & float) const age: number = 25booleantrue/false values const isActive: boolean = truenullIntentional absence const value: null = nullundefinedUninitialized value let value: undefinedanyAny type (avoid) const data: any = {...}voidNo return value function log(): void { }neverNever returns function error(): never { throw new Error() }
Array Types
// Array notation
const numbers : number [] = [ 1 , 2 , 3 ];
const names : string [] = [ "Alice" , "Bob" ];
// Generic notation
const items : Array < string > = [ "item1" , "item2" ];
// Mixed array (tuple)
const tuple : [ string , number ] = [ "age" , 25 ];
Project Interfaces
Category Interface
interface Category {
id : number ;
name : string ;
image : string ;
slug : string ;
}
Property Type Description idnumberUnique category identifier namestringCategory name (e.g., “Electronics”) imagestringURL to category image slugstringURL-friendly name
Product Interface
interface Product {
id : number ;
title : string ;
slug : string ;
price : number ;
description : string ;
category : Category ;
images : string [];
}
Product Interface Breakdown
Property Type Description Example idnumberUnique product ID 101titlestringProduct name "Laptop HP 15"slugstringURL slug "laptop-hp-15"pricenumberPrice in currency 799.99descriptionstringProduct description "Powerful laptop..."categoryCategoryNested category object { id: 1, name: "Electronics", ... }imagesstring[]Array of image URLs ["url1.jpg", "url2.jpg"]
AppState Interface
interface AppState {
status : LoadingState ;
products : Product [];
error : string | null ;
}
Property Type Description statusLoadingStateCurrent loading state (enum) productsProduct[]Array of products errorstring | nullError message or null
string | null is a union type - the value can be either a string OR null.
Enums
LoadingState Enum
enum LoadingState {
Idle = "IDLE" ,
Loading = "LOADING" ,
Success = "SUCCESS" ,
Error = "ERROR"
}
Usage:
let appState : AppState = {
status: LoadingState . Idle , // ✓ Type-safe
products: [],
error: null
};
// Instead of error-prone strings:
// status: "IDLE" // ✗ Typos not caught
Union Types
Union types allow a value to be one of several types:
// Simple union
let value : string | number ;
value = "hello" ; // ✓
value = 42 ; // ✓
// Union with null (nullable)
let error : string | null = null ;
error = "Something went wrong" ; // ✓
// Multiple unions
type Status = "pending" | "approved" | "rejected" ;
let status : Status = "pending" ;
Generics
Generic Function
function getElement < T extends HTMLElement >( selector : string ) : T {
const element = document . querySelector < T >( selector );
if ( ! element ) {
throw new Error ( `Element not found: ${ selector } ` );
}
return element ;
}
Generic Type Parameters Explained
Syntax: <T extends HTMLElement>
T is a type parameter (placeholder for any type)
extends HTMLElement means T must be HTMLElement or a subtype
When you call the function, you specify what T is
Usage: // T becomes HTMLButtonElement
const btn = getElement < HTMLButtonElement >( "#my-btn" );
btn . disabled = true ; // ✓ TypeScript knows it's a button
// T becomes HTMLInputElement
const input = getElement < HTMLInputElement >( "#search" );
input . value = "text" ; // ✓ TypeScript knows it has .value
Generic Types
// Generic array
const items : Array < Product > = [];
// Generic Map
const cart : Map < number , number > = new Map ();
// ↑ ↑
// key type value type
// Generic Promise
async function fetchData () : Promise < Product []> {
// Returns a promise that resolves to Product[]
}
Type Aliases
// Simple alias
type ID = number ;
type Username = string ;
// Object type
type Point = {
x : number ;
y : number ;
};
// Union type alias
type Status = "idle" | "loading" | "success" | "error" ;
Function Types
Function Declarations
// Named function
function add ( a : number , b : number ) : number {
return a + b ;
}
// Arrow function
const multiply = ( a : number , b : number ) : number => {
return a * b ;
};
// Implicit return
const subtract = ( a : number , b : number ) : number => a - b ;
Function Type Signatures
// Variable with function type
let calculate : ( x : number , y : number ) => number ;
calculate = ( a , b ) => a + b ; // ✓
calculate = ( a , b ) => ` ${ a } ` ; // ✗ Returns string, not number
Async Functions
async function fetchProducts ( limit : number = 20 ) : Promise < Product []> {
const response = await fetch ( ` ${ API_URL } ?limit= ${ limit } ` );
const data = await response . json () as Product [];
return data ;
}
Async functions always return a Promise. Even if you return Product[], the actual return type is Promise<Product[]>.
Optional and Default Parameters
// Optional parameter (?)
function greet ( name ?: string ) : string {
return name ? `Hello, ${ name } ` : "Hello" ;
}
// Default parameter (=)
function fetchProducts ( limit : number = 20 ) : Promise < Product []> {
// limit defaults to 20 if not provided
}
// Optional properties in interfaces
interface User {
name : string ;
age ?: number ; // Optional
}
Type Assertions
// Using 'as' keyword
const data = await response . json () as Product [];
// Angle bracket syntax (not in JSX)
const data = < Product []> await response . json ();
// DOM element assertion
const input = document . getElementById ( "search" ) as HTMLInputElement ;
Type assertions tell TypeScript “trust me, I know this type” but don’t actually change the runtime value. Use carefully!
Utility Types
Built-in Utility Types
// Partial - makes all properties optional
interface Product {
id : number ;
title : string ;
price : number ;
}
type PartialProduct = Partial < Product >;
// { id?: number; title?: string; price?: number; }
// Required - makes all properties required
type RequiredProduct = Required < PartialProduct >;
// Pick - select specific properties
type ProductPreview = Pick < Product , "id" | "title" >;
// { id: number; title: string; }
// Omit - exclude specific properties
type ProductWithoutId = Omit < Product , "id" >;
// { title: string; price: number; }
// Readonly - makes properties read-only
type ReadonlyProduct = Readonly < Product >;
Type Guards
// typeof guard
function process ( value : string | number ) {
if ( typeof value === "string" ) {
// TypeScript knows value is string here
return value . toUpperCase ();
} else {
// TypeScript knows value is number here
return value . toFixed ( 2 );
}
}
// instanceof guard
if ( element instanceof HTMLInputElement ) {
console . log ( element . value );
}
// Truthiness guard
if ( error ) {
// error is truthy (not null or undefined)
console . error ( error );
}
Common Patterns from Project
1. State Management Type
interface AppState {
status : LoadingState ;
products : Product [];
error : string | null ;
}
let appState : AppState = {
status: LoadingState . Idle ,
products: [],
error: null
};
2. API Response Typing
async function fetchProducts ( limit : number = 20 ) : Promise < Product []> {
const response = await fetch ( ` ${ API_URL } ?limit= ${ limit } ` );
if ( ! response . ok ) {
throw new Error ( `HTTP error: ${ response . status } ` );
}
const data = await response . json () as Product [];
return data ;
}
3. Generic Helper Function
function getElement < T extends HTMLElement >( selector : string ) : T {
const element = document . querySelector < T >( selector );
if ( ! element ) {
throw new Error ( `Element not found: ${ selector } ` );
}
return element ;
}
// Usage
const button = getElement < HTMLButtonElement >( "#load-btn" );
const input = getElement < HTMLInputElement >( "#search-input" );
4. Map Data Structure
const cart : Map < number , number > = new Map ();
// Add to cart
cart . set ( productId , quantity );
// Get quantity
const qty = cart . get ( productId ); // number | undefined
// Check if exists
if ( cart . has ( productId )) {
// ...
}
// Remove item
cart . delete ( productId );
5. Event Handler Typing
function handleClick ( event : MouseEvent ) : void {
const target = event . target as HTMLElement ;
const button = target . closest ( "button" );
// ...
}
element . addEventListener ( "click" , handleClick );
Type Inference
TypeScript can often infer types automatically:
// Type inferred as string
const name = "Alice" ;
// Type inferred as number
const age = 25 ;
// Type inferred as number[]
const numbers = [ 1 , 2 , 3 ];
// Type inferred as Promise<Response>
const response = fetch ( "/api/data" );
// Return type inferred as number
function add ( a : number , b : number ) {
return a + b ; // Returns number
}
Let TypeScript infer types when they’re obvious. Only add explicit types when needed for clarity or to catch errors.
Best Practices
Use interfaces for object shapes
Use enums for fixed sets of values
Use union types for values that can be multiple types
Avoid any - use unknown if you must
Use generics for reusable, type-safe functions
Let TypeScript infer types when obvious
Don’t abuse type assertions (as). If you find yourself using them frequently, your types might be wrong.
Quick Reference Card
Pattern Syntax Use Case Interface interface Name { }Object shapes Type Alias type Name = ...Unions, primitives Enum enum Name { }Fixed constants Union string | numberMultiple types Optional property?: typeOptional fields Generics <T extends Base>Reusable types Array Type[] or Array<Type>Lists Promise Promise<Type>Async results Function (param: Type) => ReturnTypeFunction signatures Assertion value as TypeOverride type
Next Steps
TypeScript Basics Learn TypeScript fundamentals
Common Patterns Code patterns and examples
HTML Tags HTML reference guide