typescript 389 lines · 2 tabs

TypeScript fundamentals for type-safe front-end code

Alex Chang Feb 2026
2 tabs
// 1. Basic types
let username: string = 'Alex';
let age: number = 30;
let isActive: boolean = true;
let items: string[] = ['item1', 'item2'];
let numbers: Array<number> = [1, 2, 3];
let tuple: [string, number] = ['Alex', 30];

// 2. Interfaces
interface User {
  id: number;
  username: string;
  email: string;
  age?: number; // Optional property
  readonly createdAt: Date; // Read-only property
}

const user: User = {
  id: 1,
  username: 'alex',
  email: 'alex@example.com',
  createdAt: new Date(),
};

// user.id = 2; // OK
// user.createdAt = new Date(); // Error: readonly

// 3. Type aliases
type ID = string | number;
type Status = 'pending' | 'active' | 'inactive';

interface Product {
  id: ID;
  name: string;
  status: Status;
  price: number;
}

// 4. Functions
function greet(name: string): string {
  return `Hello, ${name}!`;
}

const add = (a: number, b: number): number => a + b;

// Optional parameters
function buildName(firstName: string, lastName?: string): string {
  return lastName ? `${firstName} ${lastName}` : firstName;
}

// Default parameters
function multiply(a: number, b: number = 1): number {
  return a * b;
}

// Rest parameters
function sum(...numbers: number[]): number {
  return numbers.reduce((total, n) => total + n, 0);
}

// Function type
type MathOperation = (a: number, b: number) => number;

const subtract: MathOperation = (a, b) => a - b;

// 5. Generics
function identity<T>(arg: T): T {
  return arg;
}

const numIdentity = identity<number>(42);
const strIdentity = identity<string>('hello');

// Generic interface
interface Response<T> {
  data: T;
  status: number;
  message: string;
}

interface UserData {
  id: number;
  name: string;
}

const response: Response<UserData> = {
  data: { id: 1, name: 'Alex' },
  status: 200,
  message: 'Success',
};

// Generic constraints
interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(arg: T): void {
  console.log(arg.length);
}

logLength('hello'); // OK
logLength([1, 2, 3]); // OK
// logLength(42); // Error: number doesn't have length

// 6. Union and intersection types
type StringOrNumber = string | number;

function formatValue(value: StringOrNumber): string {
  if (typeof value === 'string') {
    return value.toUpperCase();
  }
  return value.toFixed(2);
}

// Intersection type
interface Nameable {
  name: string;
}

interface Ageable {
  age: number;
}

type Person = Nameable & Ageable;

const person: Person = {
  name: 'Alex',
  age: 30,
};

// 7. Enums
enum UserRole {
  Admin = 'ADMIN',
  User = 'USER',
  Guest = 'GUEST',
}

interface AuthUser {
  username: string;
  role: UserRole;
}

const admin: AuthUser = {
  username: 'admin',
  role: UserRole.Admin,
};

// Numeric enum
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

// 8. Type guards
function isString(value: any): value is string {
  return typeof value === 'string';
}

function process(value: string | number) {
  if (isString(value)) {
    console.log(value.toUpperCase());
  } else {
    console.log(value.toFixed(2));
  }
}

// instanceof guard
class Dog {
  bark() {
    console.log('Woof!');
  }
}

class Cat {
  meow() {
    console.log('Meow!');
  }
}

function makeSound(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark();
  } else {
    animal.meow();
  }
}

// 9. Utility types
// Partial - makes all properties optional
interface TodoItem {
  title: string;
  description: string;
  completed: boolean;
}

function updateTodo(todo: TodoItem, updates: Partial<TodoItem>): TodoItem {
  return { ...todo, ...updates };
}

// Required - makes all properties required
type RequiredTodo = Required<Partial<TodoItem>>;

// Readonly - makes all properties readonly
const readonlyTodo: Readonly<TodoItem> = {
  title: 'Learn TypeScript',
  description: 'Study TS fundamentals',
  completed: false,
};

// readonlyTodo.completed = true; // Error: readonly

// Pick - select specific properties
type TodoPreview = Pick<TodoItem, 'title' | 'completed'>;

// Omit - exclude specific properties
type TodoInfo = Omit<TodoItem, 'completed'>;

// Record - create object type with specific keys
type PageInfo = Record<'home' | 'about' | 'contact', { title: string }>;

const pages: PageInfo = {
  home: { title: 'Home' },
  about: { title: 'About' },
  contact: { title: 'Contact' },
};

// 10. Advanced types
// Mapped types
type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

type NullableUser = Nullable<User>;

// Conditional types
type NonNullable<T> = T extends null | undefined ? never : T;

type NotNull = NonNullable<string | null>; // string

// Template literal types
type EventName = 'click' | 'focus' | 'blur';
type EventHandler = `on${Capitalize<EventName>}`;
// Result: 'onClick' | 'onFocus' | 'onBlur'
2 files · typescript Explain with highlit

TypeScript adds static typing to JavaScript for better code quality. I define types with interfaces and type aliases for clear contracts. Type annotations like : string, : number catch errors at compile time. Generics enable reusable, type-safe components with <T> syntax. Union types combine multiple types with |, while intersection types merge types with &. The enum keyword defines named constants. Type guards with typeof and instanceof narrow types. Optional chaining ?. and nullish coalescing ?? handle undefined safely. TypeScript improves IDE autocomplete, refactoring, and prevents runtime errors.


Related snips

typescript
export interface RetryOptions {
  retries: number;
  baseMs: number;
  maxMs: number;
  signal?: AbortSignal;
  onRetry?: (attempt: number, delay: number, err: unknown) => void;

Exponential backoff with jitter for retries

typescript reliability retry
by codesnips 2 tabs
javascript
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
  const success = true;

  setTimeout(() => {
    if (success) {

Promises and async/await patterns for asynchronous JavaScript

javascript promises async-await
by Alex Chang 1 tab
javascript
import { Controller } from "@hotwired/stimulus"
import Mousetrap from "mousetrap"

export default class extends Controller {
  connect() {
    // Global shortcuts

Keyboard shortcuts with Stimulus and Mousetrap

stimulus javascript ux
by Jordan Lee 2 tabs
javascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["form"]
  static values = { delay: { type: Number, default: 250 } }

Debounced live search with Stimulus + Turbo Streams

rails hotwire stimulus
by codesnips 4 tabs
typescript
import axios, { AxiosError } from 'axios'
import { v4 as uuidv4 } from 'uuid'

const api = axios.create({
  baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api/v1',
  timeout: 15000,

Axios API client with interceptors

react axios api
by Maya Patel 1 tab
typescript
import { create } from 'zustand'
import { persist } from 'zustand/middleware'

interface FilterState {
  search: string
  category: string | null

Zustand for lightweight state management

react zustand state-management
by Maya Patel 2 tabs

Share this code

Here's the card — post it anywhere.

TypeScript fundamentals for type-safe front-end code — share card
Link copied