7 New Cheat Sheets: TypeScript, Python, SQL, Markdown, Bash, Docker & Tailwind
This guide has a free tool → Open Markdown Preview
# 7 New Cheat Sheets: TypeScript, Python, SQL, Markdown, Bash, Docker & Tailwind
ToolBox now includes 12 cheat sheets in its reference library. This post covers the seven newest additions in detail - not just announcing that they exist, but actually walking through the most useful content in each one. Consider this a summary of the summaries: the concepts within each cheat sheet that developers most commonly forget, misuse, or wish they had at their fingertips.
Browse all cheat sheets at /cheatsheets. Each one is a single-page, searchable, offline-friendly reference - no ads, no sign-up walls.
---
TypeScript Cheat Sheet
TypeScript adds a type layer on top of JavaScript, but the syntax choices it makes are not always obvious to someone coming from a dynamically typed background. The TypeScript cheat sheet focuses on the parts of the type system developers reach for most - and most often get wrong.
Type Annotations Fundamentals
// Primitive types
let name: string = "Alice";
let age: number = 30;
let active: boolean = true;
let data: null = null;
let id: undefined = undefined;
// Arrays
let tags: string[] = ["typescript", "javascript"];
let scores: Array<number> = [98, 87, 95];
// Tuples (fixed-length, typed arrays)
let point: [number, number] = [10, 20];
let entry: [string, number, boolean] = ["Alice", 30, true];
// Union types
let value: string | number = "hello";
value = 42; // also valid
// Intersection types
type AdminUser = User & Admin;Interfaces vs. Type Aliases
This is one of the most common sources of TypeScript confusion. Both create named type shapes, but they have different capabilities:
// Interface - can be extended and merged
interface User {
id: number;
name: string;
}
interface User {
email: string; // Declaration merging - adds to the existing interface
}
interface AdminUser extends User {
permissions: string[];
}
// Type alias - more flexible, supports unions and intersections
type ID = string | number;
type Point = { x: number; y: number };
type AdminUser = User & { permissions: string[] };Rule of thumb: Use interface for objects and classes you might extend. Use type for unions, intersections, primitives, and utility types.
Generics
Generics let you write reusable, type-safe code without losing specificity:
// Generic function
function identity<T>(value: T): T {
return value;
}
identity<string>("hello"); // Returns string
identity<number>(42); // Returns number
// Generic with constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Generic interface
interface Repository<T> {
findById(id: number): T;
findAll(): T[];
save(item: T): void;
}Utility Types Reference
TypeScript ships with built-in utility types that transform existing types. These are the ones the cheat sheet covers most thoroughly because they save enormous amounts of repetitive typing:
| Utility Type | What It Does | Example | |||
|---|---|---|---|---|---|
Partial<T> | Makes all properties optional | Partial<User> - all User fields optional | |||
Required<T> | Makes all properties required | Required<Partial<User>> - back to required | |||
Readonly<T> | Makes all properties read-only | Readonly<Config> | |||
Pick<T, K> | Keeps only specified keys | `Pick<User, 'id' \ | 'name'>` | ||
Omit<T, K> | Removes specified keys | Omit<User, 'password'> | |||
Record<K, V> | Maps keys to value type | Record<string, number> | |||
Exclude<T, U> | Removes union members | `Exclude<'a' \ | 'b' \ | 'c', 'a'> → 'b' \ | 'c'` |
Extract<T, U> | Keeps only matching union members | `Extract<string \ | number, string> → string` | ||
NonNullable<T> | Removes null and undefined | `NonNullable<string \ | null> → string` | ||
ReturnType<T> | Extracts a function's return type | ReturnType<typeof fetchUser> |
// Practical Partial example - updating only some fields
interface User {
id: number;
name: string;
email: string;
role: string;
}
function updateUser(id: number, updates: Partial<User>) {
// Only the provided fields are updated
}
updateUser(1, { name: "Bob" }); // Valid - email and role are optional hereType Guards
Type guards narrow a union type to a specific member:
// typeof guard
function processInput(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase(); // TypeScript knows it's a string here
}
return value.toFixed(2); // TypeScript knows it's a number here
}
// instanceof guard
function formatDate(date: Date | string) {
if (date instanceof Date) {
return date.toISOString();
}
return new Date(date).toISOString();
}
// Custom type guard (type predicate)
interface Cat { meow(): void; }
interface Dog { bark(): void; }
function isCat(animal: Cat | Dog): animal is Cat {
return (animal as Cat).meow !== undefined;
}unknown vs. any
The unknown type is TypeScript's type-safe alternative to any:
// any - disables type checking entirely
let value: any = "hello";
value.toUpperCase(); // No error, even if value is not a string
value.nonExistentMethod(); // Also no error - dangerous
// unknown - requires type checking before use
let safeValue: unknown = "hello";
// safeValue.toUpperCase(); // Error: Object is of type 'unknown'
if (typeof safeValue === "string") {
safeValue.toUpperCase(); // Now safe - TypeScript knows it's a string
}Use unknown when you genuinely do not know the type (external API responses, user input). Use any only as a last resort or during migration.
---
Markdown Preview
Free online markdown preview - write Markdown and see a live rendered preview side by side
Markdown Table Generator
Free online markdown table generator - create Markdown tables visually with an interactive editor
Tailwind Component Preview
Free online tailwind component preview - write Tailwind CSS HTML and preview components live in the browser
Python Cheat Sheet
Python's standard library and syntax shortcuts are enormous. The Python cheat sheet focuses on the idioms developers use daily but frequently look up - comprehensions, f-strings, decorators, and the parts of the standard library that replace five lines with one.
List and Dict Comprehensions
# List comprehension - basic
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# List comprehension with condition
even_squares = [x**2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]
# Dict comprehension
word_lengths = {word: len(word) for word in ["hello", "world", "python"]}
# {'hello': 5, 'world': 5, 'python': 6}
# Set comprehension
unique_lengths = {len(word) for word in ["hello", "world", "python", "hi"]}
# {2, 5, 6}
# Nested comprehension
matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]F-Strings
name = "Alice"
age = 30
pi = 3.14159
# Basic interpolation
print(f"Hello, {name}!")
# Expression evaluation
print(f"In 5 years: {age + 5}")
# Format specifiers
print(f"Pi: {pi:.2f}") # Pi: 3.14
print(f"Large: {10000:,}") # Large: 10,000
print(f"Percent: {0.85:.1%}") # Percent: 85.0%
print(f"Hex: {255:#x}") # Hex: 0xff
print(f"Padded: {name:>10}") # Padded: Alice (right-aligned)
# Debugging (Python 3.8+)
print(f"{name=}") # name='Alice'
print(f"{age=}") # age=30Decorators
import functools
import time
# Basic decorator
def timer(func):
@functools.wraps(func) # Preserves the original function's metadata
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} took {end - start:.4f}s")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
# Decorator with arguments
def repeat(times):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")Context Managers
# File handling - automatic close
with open("data.txt", "r") as f:
content = f.read()
# File is closed here automatically
# Multiple context managers
with open("input.txt") as infile, open("output.txt", "w") as outfile:
outfile.write(infile.read().upper())
# Custom context manager with class
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
self.elapsed = time.time() - self.start
with Timer() as t:
time.sleep(0.5)
print(f"Elapsed: {t.elapsed:.2f}s")
# Custom context manager with contextlib
from contextlib import contextmanager
@contextmanager
def managed_resource():
resource = acquire_resource()
try:
yield resource
finally:
release_resource(resource)Standard Library One-Liners
import json, pathlib, datetime, collections, itertools
# JSON
data = json.loads('{"key": "value"}')
json_string = json.dumps(data, indent=2)
# File I/O (pathlib)
text = pathlib.Path("file.txt").read_text()
pathlib.Path("output.txt").write_text("hello")
files = list(pathlib.Path(".").glob("*.py"))
# DateTime
now = datetime.datetime.now()
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
parsed = datetime.datetime.strptime("2026-03-02", "%Y-%m-%d")
# Collections
counter = collections.Counter("abracadabra")
# Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
most_common = counter.most_common(3)
# [('a', 5), ('b', 2), ('r', 2)]
# defaultdict
word_count = collections.defaultdict(int)
for word in "the quick brown fox".split():
word_count[word] += 1
# itertools
pairs = list(itertools.combinations([1, 2, 3, 4], 2))
# [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
batches = [list(b) for b in itertools.batched(range(10), 3)]
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]---
SQL Cheat Sheet
SQL is used by nearly every backend developer but its syntax for advanced features - window functions, CTEs, different JOIN types - is not always committed to memory. The SQL cheat sheet covers the operations that appear most in real-world query work.
JOIN Types Visualized
-- INNER JOIN: Only rows that match in both tables
SELECT u.name, o.total
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
-- LEFT JOIN: All rows from users, NULL for orders with no match
SELECT u.name, o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
-- RIGHT JOIN: All rows from orders, NULL for users with no match
SELECT u.name, o.total
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;
-- FULL OUTER JOIN: All rows from both tables
SELECT u.name, o.total
FROM users u
FULL OUTER JOIN orders o ON u.id = o.user_id;
-- CROSS JOIN: Every combination (Cartesian product)
SELECT colors.name, sizes.name
FROM colors
CROSS JOIN sizes;| JOIN Type | Returns |
|---|---|
| INNER JOIN | Matching rows from both tables |
| LEFT JOIN | All from left, matching from right (NULL if no match) |
| RIGHT JOIN | All from right, matching from left (NULL if no match) |
| FULL OUTER JOIN | All rows from both tables, NULLs where no match |
| CROSS JOIN | Every combination of rows from both tables |
Window Functions
Window functions are one of the most powerful and most underused SQL features:
-- ROW_NUMBER: Sequential number per partition
SELECT
name,
department,
salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_in_dept
FROM employees;
-- RANK and DENSE_RANK
-- RANK skips numbers after ties; DENSE_RANK does not
SELECT
name,
salary,
RANK() OVER (ORDER BY salary DESC) AS rank,
DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank
FROM employees;
-- LAG and LEAD: Access adjacent rows
SELECT
date,
revenue,
LAG(revenue, 1) OVER (ORDER BY date) AS prev_revenue,
revenue - LAG(revenue, 1) OVER (ORDER BY date) AS day_over_day_change
FROM daily_sales;
-- Running totals
SELECT
date,
amount,
SUM(amount) OVER (ORDER BY date ROWS UNBOUNDED PRECEDING) AS running_total
FROM transactions;Common Table Expressions (CTEs)
-- Basic CTE
WITH active_users AS (
SELECT id, name, email
FROM users
WHERE last_login > NOW() - INTERVAL '30 days'
)
SELECT au.name, COUNT(o.id) AS order_count
FROM active_users au
LEFT JOIN orders o ON au.id = o.user_id
GROUP BY au.name;
-- Recursive CTE (hierarchical data)
WITH RECURSIVE category_tree AS (
-- Base case: root categories
SELECT id, name, parent_id, 0 AS depth
FROM categories
WHERE parent_id IS NULL
UNION ALL
-- Recursive case: children
SELECT c.id, c.name, c.parent_id, ct.depth + 1
FROM categories c
INNER JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree ORDER BY depth, name;GROUP BY with HAVING
-- HAVING filters on aggregate results (WHERE filters on rows before aggregation)
SELECT
department,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING COUNT(*) > 5 -- Only departments with more than 5 employees
AND AVG(salary) > 60000; -- AND average salary above 60k
-- Common mistake: using WHERE instead of HAVING for aggregates
-- Wrong:
SELECT department, COUNT(*) FROM employees WHERE COUNT(*) > 5 GROUP BY department;
-- Correct:
SELECT department, COUNT(*) FROM employees GROUP BY department HAVING COUNT(*) > 5;---
Markdown Cheat Sheet
Markdown is everywhere: GitHub READMEs, documentation sites, Notion, blog posts, and now even Slack and Linear. The Markdown cheat sheet covers standard Markdown plus GitHub-Flavored Markdown (GFM) extensions.
Core Syntax Quick Reference
# H1 Heading
## H2 Heading
### H3 Heading
**Bold text** *Italic text* ~~Strikethrough~~ `inline code`
[Link text](https://example.com)
[Link with title](https://example.com "Hover title")


> Blockquote text
> Multiple lines
--- (horizontal rule, also ___ or ***)Tables (GFM)
| Column 1 | Column 2 | Column 3 |
|---|---|---|
| Cell 1 | Cell 2 | Cell 3 |
| Cell 4 | Cell 5 | Cell 6 |
| Left-aligned | Center-aligned | Right-aligned |
|:---|:---:|---:|
| Left | Center | Right |
| Left | Center | Right |Fenced Code Blocks
const greet = (name) => Hello, ${name}!;
def greet(name):
return f"Hello, {name}!"
Task Lists (GFM)
- [x] Completed task
- [ ] Pending task
- [ ] Another pending taskFootnotes
Here is a reference[^1] and another[^2].
[^1]: This is the first footnote.
[^2]: This is the second footnote.Use the Markdown Preview tool to render and verify Markdown as you write it. The Markdown Table generator helps you build and format tables without manually aligning pipes.
---
Bash Cheat Sheet
Bash scripting is a skill most developers acquire incrementally, learning one construct at a time as needed. The Bash cheat sheet covers the constructs that appear most in real scripts - variable expansion, conditionals, loops, and string manipulation.
Variables and Expansion
# Variable assignment (no spaces around =)
NAME="Alice"
COUNT=10
# Expansion
echo "$NAME" # Alice
echo "${NAME}" # Alice (explicit, preferred in strings)
echo "${NAME}s" # Alices
# Default values
echo "${VALUE:-default}" # "default" if VALUE is unset or empty
echo "${VALUE:=default}" # Sets VALUE to "default" if unset, then expands
echo "${VALUE:?error msg}" # Exits with error if VALUE is unset
# Command substitution
FILES=$(ls -la)
DATE=$(date +%Y-%m-%d)Conditionals
# if/elif/else
if [ "$COUNT" -gt 5 ]; then
echo "Greater than 5"
elif [ "$COUNT" -eq 5 ]; then
echo "Equal to 5"
else
echo "Less than 5"
fi
# File tests
if [ -f "$FILE" ]; then echo "File exists"; fi
if [ -d "$DIR" ]; then echo "Directory exists"; fi
if [ -r "$FILE" ]; then echo "File is readable"; fi
if [ -z "$VAR" ]; then echo "Variable is empty"; fi
if [ -n "$VAR" ]; then echo "Variable is non-empty"; fi
# [[ ]] - extended test (bash-specific, more robust)
if [[ "$NAME" == "Alice" ]]; then echo "Match"; fi
if [[ "$NAME" =~ ^[A-Z] ]]; then echo "Starts with uppercase"; fiLoops
# for loop over list
for item in apple banana cherry; do
echo "$item"
done
# for loop over range
for i in {1..10}; do
echo "Item $i"
done
# C-style for loop
for ((i=0; i<10; i++)); do
echo "$i"
done
# while loop
while [ "$COUNT" -gt 0 ]; do
echo "$COUNT"
((COUNT--))
done
# Loop over files
for file in *.txt; do
echo "Processing: $file"
done
# Loop over command output
while IFS= read -r line; do
echo "Line: $line"
done < input.txtScript Best Practices
#!/usr/bin/env bash
set -euo pipefail
# -e: exit on any error
# -u: treat unset variables as errors
# -o pipefail: pipeline fails if any command fails
# Trap for cleanup
cleanup() {
rm -f /tmp/tempfile
}
trap cleanup EXIT
# Always quote variable expansions
echo "$variable" # Correct
echo $variable # Dangerous if variable contains spaces---
Docker Cheat Sheet
Docker commands are not always easy to recall - especially the flags for volumes, networks, and cleanup operations. The Docker cheat sheet organizes the most-used commands into a scannable reference.
Essential docker Commands
# Images
docker pull nginx:alpine # Download image
docker images # List local images
docker build -t myapp:1.0 . # Build from Dockerfile in current directory
docker rmi myapp:1.0 # Remove image
# Containers
docker run -d -p 8080:80 --name myapp nginx # Run detached, map port
docker ps # List running containers
docker ps -a # List all containers (including stopped)
docker stop myapp # Stop gracefully
docker start myapp # Start stopped container
docker rm myapp # Remove container
docker logs -f myapp # Follow logs
# Execute command in running container
docker exec -it myapp bash # Interactive shell
docker exec myapp ls /var/www # Non-interactive command
# Copy files
docker cp myapp:/etc/nginx/nginx.conf ./nginx.conf # Container to host
docker cp ./nginx.conf myapp:/etc/nginx/nginx.conf # Host to containerdocker compose
docker compose up -d # Start services in background
docker compose down # Stop and remove containers
docker compose down -v # Also remove volumes
docker compose logs -f # Follow all service logs
docker compose logs -f web # Follow specific service
docker compose ps # List service status
docker compose exec web bash # Shell into service
docker compose build # Rebuild images
docker compose pull # Pull latest imagesDockerfile Instructions Reference
FROM node:20-alpine # Base image
WORKDIR /app # Set working directory
COPY package*.json ./ # Copy files (before npm install for cache)
RUN npm ci --only=production # Run command during build
COPY . . # Copy remaining source
ENV NODE_ENV=production # Set environment variable
EXPOSE 3000 # Document which port the app uses
USER node # Switch to non-root user
CMD ["node", "server.js"] # Default command when container starts
ENTRYPOINT ["docker-entrypoint.sh"] # Override this with --entrypointCleanup Commands
# Remove stopped containers
docker container prune
# Remove unused images
docker image prune
# Remove unused images including untagged
docker image prune -a
# Remove unused volumes
docker volume prune
# Remove everything unused (containers, images, networks, build cache)
docker system prune -a
# Nuclear option - also removes volumes
docker system prune -a --volumes---
Tailwind CSS Cheat Sheet
Tailwind's utility-first approach means there are hundreds of classes, but the same ones appear in most UIs. The Tailwind cheat sheet covers the classes that appear most frequently in real components, organized for scanning rather than comprehensive documentation.
Spacing Scale Reference
Tailwind uses a consistent spacing scale. Here are the most-used values:
| Class | Size | Pixels (at default 16px base) |
|---|---|---|
p-1 / m-1 | 0.25rem | 4px |
p-2 / m-2 | 0.5rem | 8px |
p-3 / m-3 | 0.75rem | 12px |
p-4 / m-4 | 1rem | 16px |
p-6 / m-6 | 1.5rem | 24px |
p-8 / m-8 | 2rem | 32px |
p-12 / m-12 | 3rem | 48px |
p-16 / m-16 | 4rem | 64px |
Common Flexbox and Grid Patterns
<!-- Centered content -->
<div class="flex items-center justify-center">
<!-- Space between -->
<div class="flex items-center justify-between">
<!-- Column with gap -->
<div class="flex flex-col gap-4">
<!-- Responsive grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Grid with spanning -->
<div class="grid grid-cols-12 gap-4">
<div class="col-span-8">Main content</div>
<div class="col-span-4">Sidebar</div>
</div>Responsive Breakpoints
| Prefix | Min Width | Typical Target |
|---|---|---|
| (none) | 0px | Mobile |
sm: | 640px | Large phone / small tablet |
md: | 768px | Tablet |
lg: | 1024px | Desktop |
xl: | 1280px | Large desktop |
2xl: | 1536px | Extra large desktop |
Dark Mode
<!-- dark: prefix applies when the dark class is on <html> or in media query mode -->
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
Dark mode aware content
</div>Arbitrary Values
<!-- When the scale does not have exactly what you need -->
<div class="w-[720px] h-[calc(100vh-4rem)] top-[57px] bg-[#1a2b3c]">Use the Tailwind Component Preview tool to write Tailwind HTML and see it rendered live, test responsive breakpoints, and toggle dark mode without setting up a project.
---
Why Cheat Sheets Belong in a Developer Toolbox
The argument for having cheat sheets alongside interactive tools is straightforward: some tasks require knowing the right syntax, not running a computation.
When you forget the TypeScript Omit utility type syntax, you do not need a formatter or a decoder - you need a quick reference. Sending you to the official TypeScript docs for that is like using a dictionary to check spelling: technically correct, but four times slower than a spell checker.
The ToolBox cheat sheets are designed around the real question: what do developers forget most often? The content is curated based on the concepts that appear most in Stack Overflow questions, Twitter threads, and "quick reminder" Google searches - the things that are just outside the boundary of what developers keep in memory.
Each cheat sheet is:
- Single-page - no pagination, no "click to see more"
- Searchable - use Ctrl+F in your browser to find any term
- Offline-friendly - the page loads once, no external resources required
- No ads, no modals, no sign-up prompts - just the content
---
Browse All 12 Cheat Sheets
The full collection is available at /cheatsheets:
- TypeScript
- Python
- SQL
- Markdown
- Bash
- Docker
- Tailwind CSS
- (Plus 5 existing cheat sheets for HTML, CSS, JavaScript, Git, and Linux commands)
Use them alongside the interactive tools for the most efficient workflow. When you know the SQL syntax you need, paste it into the SQL Formatter to clean it up before use. When you write Markdown tables, use the Markdown Table generator to handle alignment. When you test TypeScript generics, use the Code Formatter to keep your examples clean.
The cheat sheets and the interactive tools are designed to complement each other - the sheets answer "what is the syntax?" and the tools answer "does this work?".
You might also like
Want higher limits, batch processing, and AI tools?