Lab 13: Branded Types & Security
Step 1: Environment Setup
docker run -it --rm node:20-alpine sh
npm install -g typescript ts-node
mkdir lab13 && cd lab13
npm init -y
echo '{"compilerOptions":{"module":"commonjs","target":"es2020","strict":true}}' > tsconfig.jsonStep 2: Basic Branded Types
// brands.ts
// Method 1: Intersection with a phantom type
type Brand<T, B extends string> = T & { readonly __brand: B };
// Convenience type aliases
type UserId = Brand<string, 'UserId'>;
type ProductId = Brand<string, 'ProductId'>;
type OrderId = Brand<string, 'OrderId'>;
type Email = Brand<string, 'Email'>;
type PositiveNumber = Brand<number, 'PositiveNumber'>;
// Factory functions (the only way to create branded values)
function asUserId(id: string): UserId { return id as UserId; }
function asProductId(id: string): ProductId { return id as ProductId; }
function asEmail(s: string): Email {
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s)) throw new Error('Invalid email');
return s as Email;
}
function asPositiveNumber(n: number): PositiveNumber {
if (n <= 0) throw new Error('Must be positive');
return n as PositiveNumber;
}
// Functions that require specific brands
function getUserById(id: UserId): string { return `User: ${id}`; }
function getProductById(id: ProductId): string { return `Product: ${id}`; }
function sendEmail(to: Email, subject: string): void {
console.log(`Sending email to ${to}: ${subject}`);
}
const uid = asUserId('usr_abc123');
const pid = asProductId('prod_xyz789');
const email = asEmail('[email protected]');
// ✅ Correct usage
console.log(getUserById(uid));
console.log(getProductById(pid));
sendEmail(email, 'Welcome!');
// ❌ These would be compile-time errors (uncomment to see):
// getUserById(pid); // Error: ProductId is not assignable to UserId
// getProductById(uid); // Error: UserId is not assignable to ProductId
// getUserById('raw-string'); // Error: string is not assignable to UserId
console.log('Branded types verified!');Step 3: SQL Injection Prevention
Step 4: Secret Type — Prevent JSON Serialization
Step 5: URL Brand for XSS Prevention
Step 6: Combining Multiple Brands
Step 7: Validated Types Pattern
Step 8: Capstone — Security-First API Layer
Summary
Brand Pattern
Code
Security Benefit
Last updated
