# TypeScript Introduction for Python Developers A practical guide to TypeScript, written for Python developers. --- ## Table of Contents 1. [What is TypeScript?](#what-is-typescript) 2. [Strengths & Weaknesses](#strengths--weaknesses) 3. [Typical Use Cases](#typical-use-cases) 4. [Basic Syntax](#basic-syntax) - [Variables: `const` and `let`](#variables-const-and-let) - [Functions](#functions) - [Type Annotations](#type-annotations) 5. [Arrays](#arrays) - [Array Methods: `find`, `filter`, `map`, `flatMap`](#array-methods-find-filter-map-flatmap) - [Slicing and Indexing](#slicing-and-indexing) 6. [Handling Null and Undefined](#handling-null-and-undefined) - [Optional Chaining `?.`](#optional-chaining-) - [Nullish Coalescing `??`](#nullish-coalescing-) 7. [Strings and Template Literals](#strings-and-template-literals) 8. [Guard Clauses and Validation](#guard-clauses-and-validation) 9. [Date Handling](#date-handling) 10. [Code Style](#code-style) 11. [Quick Reference: Python to TypeScript](#quick-reference-python-to-typescript) --- ## What is TypeScript? TypeScript is a superset of JavaScript that adds **static type checking**. Your TypeScript code compiles (transpiles) to plain JavaScript, which then runs in browsers, Node.js, or anywhere JavaScript runs. ```ts // TypeScript (what you write) function greet(name: string): string { return `Hello, ${name}`; } ``` ```js // JavaScript (what runs) function greet(name) { return "Hello, " + name; } ``` The key difference from Python: TypeScript checks types **at compile time**, while Python checks types at **runtime**. This means many bugs are caught before your code runs. --- ## Strengths & Weaknesses ### Strengths | Benefit | Description | |---------|-------------| | **Early bug detection** | Type errors are caught during development, not in production | | **Better IDE support** | Autocomplete, inline docs, and refactoring work reliably | | **Self-documenting code** | Types serve as living documentation | | **Safer refactoring** | Rename a function and the compiler finds all call sites | | **Gradual adoption** | Add TypeScript to existing JavaScript projects incrementally | ### Weaknesses | Drawback | Description | |----------|-------------| | **Compilation step** | Requires a build process (though often simple) | | **Learning curve** | Advanced types can be complex | | **Boilerplate** | Type annotations add extra syntax | | **Type system limits** | Complex runtime patterns may not fit static typing easily | ### Comparison with Python | Aspect | TypeScript | Python | |--------|-----------|--------| | Typing | Static (compile time) | Dynamic (runtime) | | Type inference | Yes (often inferrable) | Yes (via type hints) | | Null safety | Optional (strict mode) | Via type hints | | Null representation | `null`, `undefined` | `None` | | Execution | Compiles to JS | Interpreted | --- ## Typical Use Cases TypeScript shines in: - **Frontend web applications** (React, Vue, Angular all support TypeScript) - **Node.js backends** (APIs, microservices) - **Large codebases** where refactoring and maintenance matter - **Teams** where code review and shared understanding are important - **Projects needing stability** (banking, healthcare, enterprise software) Python still leads in data science, ML/AI, scripting, and rapid prototyping. --- ## Basic Syntax ### Variables: `const` and `let` TypeScript uses `const` for variables that won't be reassigned, and `let` for those that will. Avoid `var`. ```ts const apiBase = 'https://api.example.com'; // Cannot be reassigned let count = 0; // Can be reassigned count = count + 1; ``` **Important:** `const` prevents reassignment but doesn't make objects immutable: ```ts const config = { retries: 2 }; config.retries = 3; // Allowed: mutating the object // config = {}; // Error: reassigning the variable ``` **Python comparison:** ```python API_BASE = 'https://api.example.com' # Convention only, not enforced count = 0 ``` ### Functions Basic function declaration with type annotations: ```ts function greet(name: string): string { return `Hello, ${name}`; } ``` With optional parameters and defaults: ```ts function buildWeeklyPeriods( dateRange?: DateRange, now = new Date(), ): string[] { // ... } ``` - `?:` marks a parameter as optional - `= value` provides a default - `: type` declares the return type **Python comparison:** ```python def greet(name: str) -> str: return f"Hello, {name}" def build_weekly_periods(date_range=None, now=None): if now is None: now = datetime.now() ``` ### Type Annotations Type annotations come **after** the variable/parameter name (opposite of Python): ```ts const name: string = 'Alice'; const age: number = 30; const isActive: boolean = true; ``` Common basic types: | TypeScript | Python | Description | |------------|--------|-------------| | `string` | `str` | Text | | `number` | `int` / `float` | All numbers | | `boolean` | `bool` | True / False | | `undefined` | — | Uninitialized | | `null` | `None` | Intentional absence | | `string[]` | `List[str]` | Array of strings | --- ## Arrays TypeScript arrays are typed and support the same operations as Python lists. ```ts const parts = [ { type: 'year', value: '2026' }, { type: 'month', value: '03' }, { type: 'day', value: '24' }, ]; // Access by index const first = parts[0]; // Array length const count = parts.length; ``` ### Array Methods: `find`, `filter`, `map`, `flatMap` **`find`** — Get the first matching element: ```ts const yearPart = parts.find((part) => part.type === 'year'); console.log(yearPart); // { type: 'year', value: '2026' } ``` Returns `undefined` if no match found. **Python comparison:** ```python year_part = next((p for p in parts if p['type'] == 'year'), None) ``` **`filter`** — Keep matching elements: ```ts const numbers = [1, 2, 3, 4, 5]; const evens = numbers.filter((n) => n % 2 === 0); console.log(evens); // [2, 4] ``` **`map`** — Transform each element: ```ts const doubled = numbers.map((n) => n * 2); console.log(doubled); // [2, 4, 6, 8, 10] ``` **`flatMap`** — Filter and transform in one pass: ```ts const result = periodStarts.flatMap((start, index) => { if (!isInRange(start)) { return []; // Drop this element } return `${start.toISOString()}/${end.toISOString()}`; // Transform }); ``` Returning `[]` removes the element; returning a value keeps it. **Python comparison:** ```python filtered = [s for s in period_starts if in_range(s)] result = [make_interval(s) for s in filtered] ``` ### Slicing and Indexing ```ts const alignedStarts: Date[] = []; // Slice: from start to before last element const periodStarts = alignedStarts.slice(0, -1); // Index access const start = alignedStarts[index]; const end = alignedStarts[index + 1]; ``` **Python comparison:** ```python period_starts = aligned_starts[:-1] start = aligned_starts[index] end = aligned_starts[index + 1] ``` --- ## Handling Null and Undefined TypeScript has two "nothing" values: `null` (explicitly set) and `undefined` (not yet assigned). Python only has `None`. ### Optional Chaining `?.` Safely access properties that might not exist: ```ts const user: { profile?: { city?: string } } = {}; const city = user.profile?.city; // undefined, no crash ``` Without `?.`, accessing `user.profile.city` when `profile` is `undefined` would throw an error. **Python comparison:** ```python city = user.profile.city if user and user.profile else None ``` ### Nullish Coalescing `??` Provide a fallback only when the value is `null` or `undefined`: ```ts const name = maybeName ?? 'anonymous'; ``` Key difference from `||`: ```ts '' || 'fallback'; // 'fallback' (empty string is falsy) '' ?? 'fallback'; // '' (only null/undefined trigger fallback) 0 || 'fallback'; // 'fallback' 0 ?? 'fallback'; // 0 ``` **Python comparison:** ```python name = x if x is not None else 'fallback' ``` ### Combining Operators for Robust Code These operators work great together: ```ts const year = parts.find((part) => part.type === 'year')?.value ?? ''; ``` Breaking it down: 1. `find(...)` returns `undefined` if no match 2. `?.value` safely accesses `value` (or returns `undefined`) 3. `?? ''` provides a fallback string This pattern is **extremely common** in TypeScript code. --- ## Strings and Template Literals ### String Literals ```ts const a = 'single quotes'; const b = "double quotes"; // Both are valid const c = ''; // Empty string ``` ### Template Literals Use backticks for string interpolation: ```ts const year = '2026'; const month = '03'; const day = '24'; const label = `${year}-${month}-${day}`; console.log(label); // '2026-03-24' ``` Template literals also support multi-line strings: ```ts const html = `

Title

`; ``` **Python comparison:** ```python label = f"{year}-{month}-{day}" html = """

Title

""" ``` --- ## Guard Clauses and Validation Guard clauses exit early when conditions are not met: ```ts if (rangeStart !== undefined && rangeEnd !== undefined && rangeStart > rangeEnd) { return []; } ``` - `!==` — strict "not equal" (use this, not `!=`) - `===` — strict "equal" (use this, not `==`) ```ts 1 === 1; // true 1 === '1'; // false (different types) 0 === false; // false (different types) ``` Always prefer strict equality (`===` / `!==`) to avoid subtle type coercion bugs. **Python comparison:** ```python if range_start is not None and range_end is not None and range_start > range_end: return [] ``` --- ## Date Handling ### Getting Timestamps ```ts const startTime = start.getTime(); ``` Returns milliseconds since Unix epoch (1970-01-01). Compare timestamps directly: ```ts if (startTime >= rangeStart && startTime <= rangeEnd) { // ... } ``` ### Converting to ISO Strings ```ts const interval = `${start.toISOString()}/${end.toISOString()}`; ``` Output: ``` 2026-03-23T23:00:00.000Z/2026-03-30T22:00:00.000Z ``` The `Z` indicates UTC timezone. **Python comparison:** ```python start_ts_ms = int(start_dt.timestamp() * 1000) interval = f"{start.isoformat()}/{end.isoformat()}" ``` --- ## Code Style ### Semicolons TypeScript/JavaScript allows optional semicolons. Most projects choose one style and stick with it: ```ts // With semicolons (common in TypeScript) const x = 1; const y = 2; // Without semicolons (also valid) const x = 1 const y = 2 ``` **Follow your project's convention.** Most TypeScript projects use semicolons. ### Equality | Operator | Use case | |----------|----------| | `===` | Always use for comparisons (strict equality) | | `!==` | Always use for comparisons (strict inequality) | | `==` | Avoid (allows type coercion) | | `!=` | Avoid (allows type coercion) | ### Robust Patterns The idiomatic way to safely extract values: ```ts function safePart(parts: Part[], wanted: string): string { return parts.find((p) => p.type === wanted)?.value ?? ''; } ``` This function: - Returns `undefined` if no matching part exists - Uses `?.` to safely access `.value` - Uses `?? ''` to ensure a string is always returned --- ## Quick Reference: Python to TypeScript ### Functions ```python def fn(x: int) -> str: return str(x) ``` ```ts function fn(x: number): string { return String(x); } ``` ### Lambda / Arrow Functions ```python lambda x: x + 1 ``` ```ts (x) => x + 1 ``` ### Fallback for Missing Values ```python value = x if x is not None else 'fallback' ``` ```ts const value = x ?? 'fallback'; ``` ### String Interpolation ```python f"{year}-{month}-{day}" ``` ```ts `${year}-${month}-${day}` ``` ### Find First Match ```python next((p for p in parts if p['type'] == 'year'), None) ``` ```ts parts.find((p) => p.type === 'year') ``` ### Array Filtering ```python filtered = [x for x in items if x.active] ``` ```ts const filtered = items.filter((x) => x.active); ``` ### Array Mapping ```python mapped = [x.name for x in items] ``` ```ts const mapped = items.map((x) => x.name); ``` ### None Checks ```python if user and user.profile: city = user.profile.city else: city = None ``` ```ts const city = user.profile?.city; ``` ### Return Type Annotations ```python from typing import List def get_names() -> List[str]: return ['Alice', 'Bob'] ``` ```ts function getNames(): string[] { return ['Alice', 'Bob']; } ``` --- ## Next Steps Now that you understand the fundamentals, explore: - **Interfaces and Types** — Define custom shapes for your data - **Generics** — Write reusable functions that work with any type - **Enums** — Define fixed sets of values - **Modules** — Organize code across files - **TypeScript with React/Vue/Node** — Apply these concepts in real frameworks --- *Based on TypeScript learning notes from the d-fine vault.*