TypeScript Cheatsheet

Modules

Use this TypeScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

ES Module Syntax

// Named export
export const PI = 3.14159;
export function add(a: number, b: number): number { return a + b; }
export class Logger { log(msg: string) { console.log(msg); } }
export interface Config { port: number; }
export type UserId = string;

// Default export (only one per file)
export default function greet(name: string): string {
  return `Hello, ${name}`;
}

// Export list (rename with `as`)
const x = 1;
const y = 2;
export { x, y };
export { x as xVal, y as yVal };

Import Syntax

// Named import
import { add, Logger } from "./utils";

// Rename on import
import { add as sum, Logger as Log } from "./utils";

// Default import
import greet from "./greet";

// Default + named
import greet, { PI, Logger } from "./module";

// Namespace import — all exports under one object
import * as MathUtils from "./math";
MathUtils.add(1, 2);
MathUtils.PI;

// Side-effect only import
import "./polyfill";

// Type-only import (stripped at compile time — no runtime import)
import type { User } from "./types";
import type { Config, UserId } from "./config";

Type-Only Imports and Exports

// import type — guarantees erasure at emit; preferred when importing only types
import type { User, Config } from "./types";
import type { EventEmitter } from "events";

// export type — export a type (not a value)
export type { User };
export type { Config as AppConfig };

// Inline type modifier (TS 4.5+) — mix type and value imports
import { type User, createUser } from "./user";

// Why use import type?
// - Avoids circular dependency issues
// - Required for --isolatedModules
// - Clearer intent
// - Eliminated entirely by bundlers (no runtime cost)

Re-Exporting

// Re-export all named exports
export * from "./math";

// Re-export and rename
export { add as sum } from "./math";

// Re-export default as named
export { default as greet } from "./greet";

// Re-export with type
export type { User } from "./types";

// Barrel file pattern (index.ts)
export * from "./user";
export * from "./post";
export * from "./comment";
export { default as App } from "./App";

Module Resolution

// Relative paths — resolved relative to current file
import "./sibling";
import "../parent/module";
import "../../deep/module";

// Non-relative — resolved via node_modules or paths config
import express from "express";
import { z } from "zod";

// tsconfig.json path aliases
// "paths": { "@/*": ["./src/*"] }
import { Button } from "@/components/Button";

// tsconfig.json baseUrl
// "baseUrl": "./src"
import { helper } from "utils/helper"; // resolves to src/utils/helper.ts

// Module resolution strategies
// "moduleResolution": "NodeNext" — for Node ESM (requires .js extension)
// "moduleResolution": "bundler" — for bundlers (Vite, webpack; no extension required)
// "moduleResolution": "node"    — classic CommonJS (legacy)

CommonJS Interop

// Importing CJS default export (with esModuleInterop: true)
import fs from "fs";
import path from "path";

// Without esModuleInterop
import * as fs from "fs";

// require() — available in Node CJS context
const data = require("./data.json");

// module.exports — CJS style output
// In .ts files, prefer ES module syntax; the compiler handles the output

// Explicit CJS interop helpers (rarely needed)
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const pkg = require("./package.json");

Dynamic Imports

// import() — returns Promise<module>; always async
const module = await import("./heavy-module");
module.doSomething();

// With type annotation
const { format } = await import("./formatter") as { format: (s: string) => string };

// Conditional loading
async function loadFeature(flag: boolean) {
  if (flag) {
    const { Feature } = await import("./Feature");
    return new Feature();
  }
}

// Dynamic import in non-async context
import("./logger").then(({ Logger }) => {
  const log = new Logger();
  log.info("Loaded");
});

// Code splitting (webpack/bundler hint)
const LazyComponent = React.lazy(() => import("./LazyComponent"));

Ambient Module Declarations

// Declare a module shape for untyped JS packages
declare module "untyped-package" {
  export function doThing(x: string): number;
  export const version: string;
  export default class Thing {
    constructor(opts: Record<string, unknown>);
    run(): void;
  }
}

// Wildcard module declarations (e.g., for file imports)
declare module "*.svg" {
  const content: string;
  export default content;
}

declare module "*.png" {
  const src: string;
  export default src;
}

declare module "*.json" {
  const value: unknown;
  export default value;
}

// CSS modules
declare module "*.module.css" {
  const styles: { readonly [key: string]: string };
  export default styles;
}

Declaration Files (.d.ts)

// lib.d.ts — ships with TypeScript; declares built-in globals

// yourlib.d.ts — declare types for a JS library
export declare function parse(input: string): number;
export declare class Parser {
  constructor(options?: ParserOptions);
  parse(input: string): AST;
}
export declare interface ParserOptions {
  strict?: boolean;
  encoding?: BufferEncoding;
}

// global augmentation in .d.ts
declare global {
  interface Window {
    myLib: { version: string };
  }
  var __DEV__: boolean;
}
export {}; // Needed to make this a module (not a script)

Module Augmentation

// Augment a third-party module's types
import "express";
declare module "express" {
  interface Request {
    user?: { id: string; role: string };
    sessionId?: string;
  }
}

// Augment built-in types
declare global {
  interface Array<T> {
    last(): T | undefined;
  }
}
Array.prototype.last = function() { return this[this.length - 1]; };

// Augment a class (rarely needed)
declare module "./MyClass" {
  interface MyClass {
    extraMethod(): void;
  }
}

Namespaces (Legacy)

// Namespaces group related declarations (prefer ES modules)
namespace Validation {
  export interface StringValidator {
    isAcceptable(s: string): boolean;
  }

  export class LettersOnlyValidator implements StringValidator {
    isAcceptable(s: string): boolean {
      return /^[A-Za-z]+$/.test(s);
    }
  }
}

const v: Validation.StringValidator = new Validation.LettersOnlyValidator();

// Nested namespace
namespace Shapes {
  export namespace Polygons {
    export class Triangle {}
    export class Square {}
  }
}
const t = new Shapes.Polygons.Triangle();

// Merging namespace with a function
function buildLabel(name: string): string {
  return buildLabel.prefix + name + buildLabel.suffix;
}
namespace buildLabel {
  export let suffix = "";
  export let prefix = "Hello, ";
}

import.meta (ESM)

// Available in ESM context
import.meta.url;          // current file URL
import.meta.env;          // Vite / bundler env vars
import.meta.env.MODE;     // "development" | "production"
import.meta.env.VITE_API; // user-defined env var

// Node.js
import.meta.dirname;      // Node 21.2+ (equivalent of __dirname)
import.meta.filename;     // Node 21.2+ (equivalent of __filename)
import.meta.resolve("./dep"); // resolve relative to current file

Triple-Slash References (Legacy)

/// <reference path="./other-file.ts" />       // explicit dependency
/// <reference types="node" />                  // include @types/node
/// <reference lib="ES2022" />                  // include lib file
/// <reference no-default-lib="true" />         // opt out of default libs

// Modern alternative: just use tsconfig.json
// { "compilerOptions": { "types": ["node"], "lib": ["ES2022", "DOM"] } }

Exports and Module Format Notes

// package.json "exports" field (Node.js / bundlers)
// {
//   "exports": {
//     ".": {
//       "import": "./dist/index.mjs",
//       "require": "./dist/index.cjs",
//       "types": "./dist/index.d.ts"
//     }
//   }
// }

// TypeScript 4.7+ — .mts and .cts file extensions
// .mts → emits .mjs (ESM)
// .cts → emits .cjs (CJS)
// .ts  → respects "module" in tsconfig

// Verbatim module syntax (TS 5.0+)
// "verbatimModuleSyntax": true
// Forces: type-only imports must use `import type`; each import is emitted as-is