From Python to TypeScript
You're building an AI chat interface that streams responses token-by-token. Your Python backend handles the agent logic—tool calls, reasoning, memory. But the browser running that chat UI speaks a different language: TypeScript. Every streaming chunk, every user keystroke, every animated typing indicator runs in TypeScript.
The good news: you already know how to program. Python taught you variables, functions, loops, and type hints. TypeScript uses the same concepts with different syntax. This lesson maps your Python knowledge to TypeScript equivalents, so you can read and write TypeScript code by the end.
This isn't about learning programming from scratch. It's about translation—taking mental models you've built and expressing them in a new syntax that browsers understand.
Variable Declarations
Python uses dynamic assignment. TypeScript requires explicit declaration keywords.
Python Variables
# Python: assign directly, type is inferred
name = "Claude"
age = 3
is_active = True
# Python: optional type hints
name: str = "Claude"
age: int = 3
is_active: bool = True
Output:
# These create variables in Python's namespace
# Type hints are optional and don't enforce anything at runtime
TypeScript Variables
TypeScript uses let for mutable variables and const for immutable ones:
// TypeScript: declare with let (mutable)
let name: string = "Claude";
let age: number = 3;
let isActive: boolean = true;
// TypeScript: declare with const (immutable)
const MODEL_NAME: string = "claude-3-opus";
const MAX_TOKENS: number = 4096;
Output:
// Variables are created with explicit mutability
// const prevents reassignment: MODEL_NAME = "gpt-4" would error
Key Differences
| Concept | Python | TypeScript |
|---|---|---|
| Mutable variable | x = 5 | let x: number = 5 |
| Immutable variable | X = 5 (convention) | const X: number = 5 |
| Type annotation | x: int = 5 | x: number = 5 |
| Boolean type | bool | boolean |
| No value | None | null or undefined |
TypeScript enforces const at compile time. If you try to reassign a const variable, your code won't compile:
const apiKey: string = "sk-abc123";
apiKey = "sk-xyz789"; // Error: Cannot assign to 'apiKey' because it is constant
Output:
error TS2588: Cannot assign to 'apiKey' because it is a constant.
Type Inference
TypeScript can often infer types from values, just like Python:
// Explicit types
const name: string = "Claude";
const age: number = 3;
// Inferred types (TypeScript figures it out)
const name = "Claude"; // TypeScript knows this is string
const age = 3; // TypeScript knows this is number
Output:
// Both approaches work. Inferred types reduce verbosity.
// Hover over variables in VS Code to see inferred types.
For learning, we'll use explicit types. Once comfortable, you can let TypeScript infer where appropriate.
Function Syntax
Functions are where TypeScript's type system shines. You declare types for parameters and return values.
Python Functions
def greet(name: str) -> str:
return f"Hello, {name}!"
def calculate_tokens(text: str, model: str = "gpt-4") -> int:
# Simplified token estimation
return len(text) // 4
# Calling functions
message = greet("Alice")
tokens = calculate_tokens("Hello, world!")
Output:
Hello, Alice!
3
TypeScript Functions
function greet(name: string): string {
return `Hello, ${name}!`;
}
function calculateTokens(text: string, model: string = "gpt-4"): number {
// Simplified token estimation
return Math.floor(text.length / 4);
}
// Calling functions
const message: string = greet("Alice");
const tokens: number = calculateTokens("Hello, world!");
console.log(message);
console.log(tokens);
Output:
Hello, Alice!
3
Syntax Mapping
| Element | Python | TypeScript |
|---|---|---|
| Function keyword | def | function |
| Parameter type | name: str | name: string |
| Return type | -> str | : string (after parentheses) |
| Default value | model: str = "gpt-4" | model: string = "gpt-4" |
| String interpolation | f"Hello, {name}" | `Hello, ${name}` |
| Integer division | // | Math.floor(x / y) |
Notice the backticks for template strings in TypeScript. Single or double quotes create regular strings; backticks enable ${variable} interpolation.
Arrow Functions
TypeScript has a concise syntax for functions called arrow functions. They're similar to Python's lambda, but more powerful.
Python Lambda
# Python lambda (limited to single expression)
double = lambda x: x * 2
# Python lambda with type hints (uncommon)
double: Callable[[int], int] = lambda x: x * 2
# Call it
result = double(5) # 10
Output:
10
TypeScript Arrow Functions
// Arrow function with explicit types
const double = (x: number): number => x * 2;
// Arrow function with block body
const processMessage = (text: string): string => {
const cleaned = text.trim();
return cleaned.toLowerCase();
};
// Call them
console.log(double(5)); // 10
console.log(processMessage(" HI ")); // hi
Output:
10
hi
When to Use Arrow Functions
Arrow functions are preferred in TypeScript for:
- Callbacks and event handlers
- Array methods like
map,filter,reduce - Short utility functions
// Array operations with arrow functions
const numbers: number[] = [1, 2, 3, 4, 5];
const doubled = numbers.map((n) => n * 2);
const evens = numbers.filter((n) => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(evens); // [2, 4]
console.log(sum); // 15
Output:
[2, 4, 6, 8, 10]
[2, 4]
15
Use regular function declarations for top-level functions with names. Use arrow functions for inline expressions.
Control Flow
Control flow syntax differs slightly but maps directly from Python concepts.
If/Else
# Python
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
else:
grade = "C"
print(grade) # B
Output:
B
// TypeScript
const score: number = 85;
let grade: string;
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else {
grade = "C";
}
console.log(grade); // B
Output:
B
Key differences:
- Parentheses required around conditions:
if (condition) - Curly braces for blocks:
{ }instead of indentation else ifinstead ofelif- Semicolons end statements
For Loops
Python's for item in collection becomes TypeScript's for (const item of collection):
# Python
models = ["gpt-4", "claude-3", "gemini"]
for model in models:
print(f"Loading {model}...")
Output:
Loading gpt-4...
Loading claude-3...
Loading gemini...
// TypeScript: for...of iterates values
const models: string[] = ["gpt-4", "claude-3", "gemini"];
for (const model of models) {
console.log(`Loading ${model}...`);
}
Output:
Loading gpt-4...
Loading claude-3...
Loading gemini...
TypeScript has two for-loop variants:
for...of— iterates over values (use this for arrays)for...in— iterates over keys/indices (rarely needed)
const models: string[] = ["gpt-4", "claude-3", "gemini"];
// for...of gives values (what you usually want)
for (const model of models) {
console.log(model); // "gpt-4", "claude-3", "gemini"
}
// for...in gives indices (rarely needed)
for (const index in models) {
console.log(index); // "0", "1", "2"
}
Output:
gpt-4
claude-3
gemini
0
1
2
While Loops
# Python
count = 0
while count < 3:
print(f"Attempt {count + 1}")
count += 1
Output:
Attempt 1
Attempt 2
Attempt 3
// TypeScript
let count: number = 0;
while (count < 3) {
console.log(`Attempt ${count + 1}`);
count++;
}
Output:
Attempt 1
Attempt 2
Attempt 3
Note count++ is shorthand for count = count + 1. TypeScript also supports count-- and count += 1.
Equality Operators
TypeScript has two equality operators. Use the strict one.
// Strict equality (===) - use this
console.log(5 === 5); // true
console.log("5" === 5); // false (different types)
console.log(null === undefined); // false
// Loose equality (==) - avoid this
console.log(5 == 5); // true
console.log("5" == 5); // true (type coercion!)
console.log(null == undefined); // true (confusing!)
Output:
true
false
false
true
true
true
Always use === (strict equality) and !== (strict inequality). They compare both value and type, matching Python's behavior.
Quick Reference
| Python | TypeScript |
|---|---|
x = 5 | let x: number = 5 |
X = 5 (constant) | const X: number = 5 |
def f(x: int) -> str: | function f(x: number): string { } |
lambda x: x * 2 | (x) => x * 2 |
f"Hello, {name}" | `Hello, ${name}` |
for item in items: | for (const item of items) { } |
if x == 5: | if (x === 5) { } |
elif | else if |
None | null or undefined |
True / False | true / false |
print() | console.log() |
Try With AI
Prompt 1: Variable Translation
I have this Python code that defines configuration for an AI agent:
api_key = "sk-abc123"
model_name = "gpt-4"
max_tokens = 4096
temperature = 0.7
is_streaming = True
Convert this to TypeScript using const declarations with explicit type annotations.
Which variables should use number vs string vs boolean?
What you're learning: How TypeScript maps Python's dynamic types to explicit type declarations, and when to use const for configuration values that shouldn't change.
Prompt 2: Function Conversion
Convert this Python function to TypeScript with full type annotations:
def format_ai_response(content: str, model: str, tokens_used: int) -> dict:
return {
"content": content,
"model": model,
"tokens": tokens_used,
"timestamp": datetime.now().isoformat()
}
What TypeScript type should I use for the return value?
Should I define a custom type or use a built-in?
What you're learning: How TypeScript handles object return types, and the difference between inline type definitions and named types. This prepares you for defining AI response types in later lessons.
Prompt 3: Loop Refactoring
I have Python code that processes AI responses:
responses = [
{"role": "user", "content": "Hello"},
{"role": "assistant", "content": "Hi there!"},
{"role": "user", "content": "How are you?"}
]
for response in responses:
if response["role"] == "assistant":
print(f"AI: {response['content']}")
Convert this to TypeScript. What type should I use for the responses array?
Should I use for...of or for...in?
What you're learning: How TypeScript handles arrays of objects with specific shapes, and why for...of is the correct choice for iterating values. This pattern appears constantly when processing chat message histories.
Safety note: When experimenting with AI-generated TypeScript, run it through the TypeScript compiler (tsc --noEmit yourfile.ts) to catch type errors before runtime. The compiler is your first line of defense against bugs.