Tutorial Material

Python Type Hints

Share to

Type Hints (type annotations) are a Python feature that allows you to specify the expected data type for variables, function parameters, and return values. Introduced in Python 3.5, type hints have become increasingly important for modern Python development.

Why Use Type Hints?

Type hints provide many benefits:

Important: Type hints in Python are optional and do not affect runtime. Python remains dynamically typed.

Basic Syntax

# Variable annotation
name: str = "Budi"
age: int = 25
height: float = 175.5
active: bool = True

# Function parameter and return type annotation
def greet(name: str) -> str:
    return f"Hello, {name}!"

def add(a: int, b: int) -> int:
    return a + b

# Function without return value
def print_info(message: str) -> None:
    print(message)

Basic Data Types

# Primitive types
x: int = 10
y: float = 3.14
z: str = "hello"
flag: bool = True
data: bytes = b"hello"

# None type
result: None = None

Collection Types

For collection types, use the typing module (Python < 3.9) or built-in types (Python 3.9+):

# Python 3.9+ (recommended)
numbers: list[int] = [1, 2, 3]
name_age: dict[str, int] = {"Andi": 25, "Budi": 30}
coordinates: tuple[float, float] = (3.14, 2.71)
unique: set[str] = {"apple", "orange"}

# Python 3.5 - 3.8 (use typing)
from typing import List, Dict, Tuple, Set

numbers: List[int] = [1, 2, 3]
name_age: Dict[str, int] = {"Andi": 25}
coordinates: Tuple[float, float] = (3.14, 2.71)
unique: Set[str] = {"apple", "orange"}

Optional and Union

For values that can be None or multiple types:

from typing import Optional, Union

# Optional - can be None or a specific type
def find_user(id: int) -> Optional[str]:
    if id == 1:
        return "Andi"
    return None

# Union - can be one of several types
def process(data: Union[str, int]) -> str:
    return str(data)

# Python 3.10+ syntax (recommended)
def find_user(id: int) -> str | None:
    if id == 1:
        return "Andi"
    return None

def process(data: str | int) -> str:
    return str(data)

Callable (Function as Parameter)

from typing import Callable

# Function that accepts another function as parameter
def apply_twice(func: Callable[[int], int], value: int) -> int:
    return func(func(value))

def double(x: int) -> int:
    return x * 2

result = apply_twice(double, 5)  # 20

# Callable with multiple arguments
def operation(func: Callable[[int, int], int], a: int, b: int) -> int:
    return func(a, b)

Any Type

When the type can be anything:

from typing import Any

def process_anything(data: Any) -> Any:
    return data

Type Aliases

Create aliases for complex types:

from typing import TypeAlias

# Type alias
UserId: TypeAlias = int
UserData: TypeAlias = dict[str, str | int]

def get_user(user_id: UserId) -> UserData:
    return {"name": "Andi", "age": 25}

# For more complex types
Matrix: TypeAlias = list[list[float]]

def transpose(matrix: Matrix) -> Matrix:
    return [[row[i] for row in matrix] for i in range(len(matrix[0]))]

Generic Types

For functions that work with various types:

from typing import TypeVar

T = TypeVar('T')

def first_element(items: list[T]) -> T:
    return items[0]

# Can be used with list of any type
number = first_element([1, 2, 3])        # int
word = first_element(["a", "b", "c"])   # str

Literal Types

For values that must be specific:

from typing import Literal

def set_status(status: Literal["active", "inactive", "pending"]) -> None:
    print(f"Status: {status}")

set_status("active")    # OK
set_status("unknown")   # Type error (detected by type checker)

# Useful for limited options
Mode = Literal["read", "write", "append"]

def open_file(path: str, mode: Mode) -> None:
    pass

TypedDict

For dictionaries with a fixed structure:

from typing import TypedDict

class User(TypedDict):
    name: str
    age: int
    email: str

def create_user(data: User) -> None:
    print(f"Creating user: {data['name']}")

# Type checker will validate validity
user: User = {
    "name": "Andi",
    "age": 25,
    "email": "[email protected]"
}

Annotations for Class

class Student:
    name: str
    id: str
    gpa: float
    
    def __init__(self, name: str, id: str) -> None:
        self.name = name
        self.id = id
        self.gpa = 0.0
    
    def set_gpa(self, gpa: float) -> None:
        self.gpa = gpa
    
    def get_info(self) -> str:
        return f"{self.name} ({self.id}): GPA {self.gpa}"

Dataclasses with Type Hints

from dataclasses import dataclass

@dataclass
class Product:
    name: str
    price: float
    stock: int = 0
    
    def total_value(self) -> float:
        return self.price * self.stock

product = Product("Laptop", 15000000, 10)
print(product.total_value())  # 150000000

Tools for Type Checking

Type hints are not checked at runtime. Use the following tools:

1. mypy

pip install mypy
mypy script.py

2. pyright (VS Code Pylance)

Already integrated with VS Code via Pylance extension.

3. pytype (Google)

pip install pytype
pytype script.py

Complete Example

from dataclasses import dataclass
from typing import Optional

@dataclass
class Address:
    street: str
    city: str
    zip_code: str

@dataclass  
class Employee:
    name: str
    email: str
    salary: float
    address: Optional[Address] = None
    
    def full_info(self) -> str:
        info = f"{self.name} - {self.email}"
        if self.address:
            info += f" ({self.address.city})"
        return info

def calculate_total_salary(employee_list: list[Employee]) -> float:
    return sum(k.salary for k in employee_list)

def find_employee(
    employee_list: list[Employee], 
    name: str
) -> Employee | None:
    for k in employee_list:
        if k.name.lower() == name.lower():
            return k
    return None

# Usage
address = Address("Jl. Sudirman", "Jakarta", "12190")
e1 = Employee("Andi", "[email protected]", 10000000, address)
e2 = Employee("Budi", "[email protected]", 12000000)

all_employees = [e1, e2]
print(calculate_total_salary(all_employees))  # 22000000

Edit this tutorial

Belajarpython x DevMode Community
OFFICIAL COMMUNITY

Gabung Komunitas Developer & Kreator Digital

Dapatkan teman coding, sharing project, networking dengan expert, dan update teknologi terbaru.

Bebas spam. Unsubscribe kapan saja. DEVMODE Community