Course Progress68%
🍎 Python Practical Python Topic 68 / 100
⏳ 7 min read

Type Hints

Annotate your code with types for better editor support, fewer bugs, and code that explains itself.

"Type hints don't slow Python down or add rules — they're notes you write for yourself, your teammates, and your editor. Code with them is self-documenting."

— ShurAI

What are Type Hints?

Type hints (or type annotations) let you say what type a variable, parameter, or return value is expected to be. Python doesn’t enforce them at runtime — they’re for humans and tools like VS Code or mypy to catch bugs early:

python — without vs with type hints
# Without type hints — what types does this expect?
def greet(name):
    return "Hello, " + name

# With type hints — crystal clear
def greet(name: str) -> str:
    return "Hello, " + name

The syntax is simple: param: Type for parameters, and -> ReturnType after the parentheses for the return value.

Basic Type Annotations

python
# Variable annotations
name:     str   = "Riya"
age:      int   = 22
score:    float = 98.5
is_admin: bool  = False

# Function with parameter and return annotations
def add(a: int, b: int) -> int:
    return a + b

def is_even(n: int) -> bool:
    return n % 2 == 0

def say_hi(name: str) -> None:     # None = returns nothing
    print(f"Hi {name}!")

Collection Types

For lists, dicts, and other containers, use the built-in type directly (Python 3.9+) or import from typing for older versions:

python — Python 3.9+
def total(scores: list[int]) -> int:
    return sum(scores)

def get_user(data: dict[str, str]) -> str:
    return data["name"]

def unique(items: list[int]) -> set[int]:
    return set(items)

# Tuple with fixed types
def coords() -> tuple[float, float]:
    return (28.6, 77.2)

Optional and Union Types

Use | (Python 3.10+) to say a value can be one of multiple types, or None:

python
# int | None means "an int OR None" (optional value)
def find_user(user_id: int) -> str | None:
    users = {1: "Riya", 2: "Arjun"}
    return users.get(user_id)   # returns str or None

# int | str means "accept either type"
def display(value: int | str) -> str:
    return f"Value: {value}"

# For Python 3.9 and below, use Optional from typing
from typing import Optional
def find_old(uid: int) -> Optional[str]:  # same as str | None
    pass
Type hints are never enforced at runtime

Python won’t raise an error if you pass the wrong type. Type hints are for static analysis tools (mypy, Pyright) and IDEs (VS Code, PyCharm) to warn you before you run the code. The benefit is catching bugs early and getting better autocomplete.

Real Example — Typed Student Report

python
def average(scores: list[float]) -> float:
    return sum(scores) / len(scores)

def grade(avg: float) -> str:
    if   avg >= 90: return "A"
    elif avg >= 75: return "B"
    elif avg >= 60: return "C"
    else:           return "F"

def report(name: str, scores: list[float]) -> dict[str, str | float]:
    avg = average(scores)
    return {"name": name, "average": round(avg, 1), "grade": grade(avg)}

print(report("Riya",  [88.0, 92.5, 79.0]))
print(report("Arjun", [55.0, 61.0, 58.5]))
output
{'name': 'Riya', 'average': 86.5, 'grade': 'B'}
{'name': 'Arjun', 'average': 58.2, 'grade': 'F'}

"Add type hints to function signatures as a habit. You don't need to annotate every variable — just the inputs and outputs of functions. That alone catches 80% of type bugs."

— ShurAI

🧠 Quiz — Q1

What do type hints do at runtime?

🧠 Quiz — Q2

What does -> str after a function's parentheses mean?

🧠 Quiz — Q3

How do you annotate a parameter that can be either int or None (Python 3.10+)?

🧠 Quiz — Q4

Which annotation correctly says a function accepts a list of strings and returns nothing?