typescript
TypeScript Development
Modern TypeScript patterns and type-safe development.
Type Fundamentals
Basic Types
// Primitives
const name: string = 'John';
const age: number = 30;
const isActive: boolean = true;
const nothing: null = null;
const notDefined: undefined = undefined;
// Arrays
const numbers: number[] = [1, 2, 3];
const strings: Array<string> = ['a', 'b', 'c'];
const mixed: (string | number)[] = [1, 'two', 3];
// Tuples
const tuple: [string, number] = ['hello', 42];
const namedTuple: [name: string, age: number] = ['John', 30];
// Objects
const user: { name: string; age: number } = { name: 'John', age: 30 };
// Any vs Unknown
const dangerous: any = getData(); // Avoid - no type checking
const safe: unknown = getData(); // Prefer - requires type narrowing
if (typeof safe === 'string') {
console.log(safe.toUpperCase()); // Now TypeScript knows it's string
}
Interfaces vs Types
// Interface - extendable, for objects
interface User {
id: number;
name: string;
email: string;
}
interface AdminUser extends User {
role: 'admin';
permissions: string[];
}
// Type - more flexible
type ID = string | number;
type Callback = (data: string) => void;
type Status = 'pending' | 'active' | 'inactive';
// Intersection types
type UserWithTimestamps = User & {
createdAt: Date;
updatedAt: Date;
};
// Use interface for objects, type for unions/primitives
Optional & Readonly
interface Config {
required: string;
optional?: string; // May be undefined
readonly immutable: string; // Can't be reassigned
}
// Readonly utility
type ReadonlyUser = Readonly<User>;
// Partial - all optional
type PartialUser = Partial<User>;
// Required - all required
type RequiredUser = Required<User>;
Generics
Basic Generics
// Generic function
function identity<T>(value: T): T {
return value;
}
const num = identity(42); // T inferred as number
const str = identity('hello'); // T inferred as string
// Generic interface
interface Response<T> {
data: T;
status: number;
message: string;
}
const userResponse: Response<User> = {
data: { id: 1, name: 'John', email: 'john@example.com' },
status: 200,
message: 'Success',
};
// Generic class
class Queue<T> {
private items: T[] = [];
enqueue(item: T): void {
this.items.push(item);
}
dequeue(): T | undefined {
return this.items.shift();
}
}
const numberQueue = new Queue<number>();
numberQueue.enqueue(1);
Constraints
// Constrain to specific shape
interface HasId {
id: number;
}
function findById<T extends HasId>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
// Multiple constraints
function merge<T extends object, U extends object>(a: T, b: U): T & U {
return { ...a, ...b };
}
// keyof constraint
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'John', age: 30 };
const name = getProperty(user, 'name'); // string
const age = getProperty(user, 'age'); // number
Utility Types
// Pick - select specific properties
type UserPreview = Pick<User, 'id' | 'name'>;
// Omit - exclude properties
type UserWithoutEmail = Omit<User, 'email'>;
// Record - map keys to values
type UserRoles = Record<string, 'admin' | 'user' | 'guest'>;
// Extract / Exclude
type Status = 'pending' | 'active' | 'deleted';
type ActiveStatus = Extract<Status, 'pending' | 'active'>; // 'pending' | 'active'
type WithoutDeleted = Exclude<Status, 'deleted'>; // 'pending' | 'active'
// ReturnType / Parameters
function createUser(name: string, email: string): User {
return { id: 1, name, email };
}
type CreateUserReturn = ReturnType<typeof createUser>; // User
type CreateUserParams = Parameters<typeof createUser>; // [string, string]
// NonNullable
type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>; // string
Type Guards
// typeof guard
function process(value: string | number) {
if (typeof value === 'string') {
return value.toUpperCase();
}
return value * 2;
}
// instanceof guard
class Dog {
bark() { console.log('Woof!'); }
}
class Cat {
meow() { console.log('Meow!'); }
}
function speak(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}
// in guard
interface Bird { fly(): void; }
interface Fish { swim(): void; }
function move(animal: Bird | Fish) {
if ('fly' in animal) {
animal.fly();
} else {
animal.swim();
}
}
// Custom type guard
interface ApiError {
code: string;
message: string;
}
function isApiError(error: unknown): error is ApiError {
return (
typeof error === 'object' &&
error !== null &&
'code' in error &&
'message' in error
);
}
// Usage
try {
await fetchData();
} catch (error) {
if (isApiError(error)) {
console.log(error.code); // TypeScript knows it's ApiError
}
}
Advanced Patterns
Discriminated Unions
interface LoadingState {
status: 'loading';
}
interface SuccessState<T> {
status: 'success';
data: T;
}
interface ErrorState {
status: 'error';
error: string;
}
type AsyncState<T> = LoadingState | SuccessState<T> | ErrorState;
function handleState<T>(state: AsyncState<T>) {
switch (state.status) {
case 'loading':
return 'Loading...';
case 'success':
return state.data; // TypeScript knows data exists
case 'error':
return state.error; // TypeScript knows error exists
}
}
Template Literal Types
type EventName = 'click' | 'focus' | 'blur';
type EventHandler = `on${Capitalize<EventName>}`; // 'onClick' | 'onFocus' | 'onBlur'
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type Endpoint = `/api/${string}`;
function request(method: HTTPMethod, url: Endpoint) {
// ...
}
request('GET', '/api/users'); // OK
request('GET', '/users'); // Error: doesn't start with /api/
Mapped Types
// Make all properties optional
type Optional<T> = {
[K in keyof T]?: T[K];
};
// Make all properties nullable
type Nullable<T> = {
[K in keyof T]: T[K] | null;
};
// Prefix keys
type Prefixed<T, P extends string> = {
[K in keyof T as `${P}${string & K}`]: T[K];
};
type PrefixedUser = Prefixed<User, 'user_'>;
// { user_id: number; user_name: string; user_email: string }
Conditional Types
// Basic conditional
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// Extract array element type
type ElementOf<T> = T extends (infer E)[] ? E : never;
type StringElement = ElementOf<string[]>; // string
// Function return type
type AsyncReturnType<T> = T extends (...args: any[]) => Promise<infer R> ? R : never;
async function fetchUser(): Promise<User> {
return { id: 1, name: 'John', email: 'john@example.com' };
}
type FetchedUser = AsyncReturnType<typeof fetchUser>; // User
React TypeScript
Component Types
import { FC, ReactNode, ComponentProps } from 'react';
// Props interface
interface ButtonProps {
variant: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
children: ReactNode;
onClick?: () => void;
}
// Function component
function Button({ variant, size = 'md', children, onClick }: ButtonProps) {
return (
<button className={`btn-${variant} btn-${size}`} onClick={onClick}>
{children}
</button>
);
}
// With FC (includes children)
const Card: FC<{ title: string; children: ReactNode }> = ({ title, children }) => (
<div className="card">
<h2>{title}</h2>
{children}
</div>
);
// Extending HTML element props
interface InputProps extends ComponentProps<'input'> {
label: string;
error?: string;
}
function Input({ label, error, ...props }: InputProps) {
return (
<div>
<label>{label}</label>
<input {...props} />
{error && <span className="error">{error}</span>}
</div>
);
}
Hooks
import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
// useState with type
const [user, setUser] = useState<User | null>(null);
const [items, setItems] = useState<string[]>([]);
// useRef
const inputRef = useRef<HTMLInputElement>(null);
const countRef = useRef<number>(0);
// useCallback with types
const handleClick = useCallback((id: number) => {
console.log(id);
}, []);
// useMemo
const expensiveValue = useMemo(() => {
return items.filter(item => item.length > 5);
}, [items]);
// Custom hook
function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = useState<T>(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}
Configuration
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
},
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Strict Mode Benefits
// strictNullChecks - catches null/undefined errors
const user: User | null = getUser();
user.name; // Error: user might be null
user?.name; // OK: optional chaining
// noImplicitAny - requires explicit types
function process(data) { } // Error: implicit 'any'
function process(data: unknown) { } // OK
// strictPropertyInitialization - ensures class properties are initialized
class User {
name: string; // Error: not initialized
name: string = ''; // OK
}
More from vapvarun/claude-backup
php
Modern PHP development best practices including PHP 8.x features, OOP patterns, error handling, security, testing, and performance optimization. Use when writing PHP code, reviewing PHP projects, debugging PHP issues, or implementing PHP features outside of WordPress/Laravel specific contexts.
45laravel
Complete Laravel development guide covering Eloquent, Blade, testing with Pest/PHPUnit, queues, caching, API resources, migrations, and Laravel best practices. Use when building Laravel applications, writing Laravel code, implementing features in Laravel, debugging Laravel issues, or when user mentions Laravel, Eloquent, Blade, Artisan, or PHP frameworks.
23email-marketing
Create email marketing campaigns including newsletters, drip sequences, promotional emails, and transactional emails. Use when writing email copy, designing email templates, or planning email automation.
14javascript
Write modern JavaScript/ES6+ code following best practices for performance, security, and maintainability. Use when writing JS code, fixing bugs, or implementing frontend functionality.
14html-markup
Write semantic, accessible HTML5 markup following best practices for structure, SEO, and accessibility. Use when creating HTML templates, fixing markup issues, or building web page structures.
12landing-page
Create high-converting landing pages with persuasive copy, clear CTAs, social proof, and optimized structure. Use when building sales pages, product pages, lead capture pages, or conversion-focused pages.
12