PROGRAMMING-CONCEPTS

Generic / Template: Definition, Purpose, and Examples

A generic (sometimes called a template in other languages) is a feature that allows you to write reusable code that works with many data types while keeping strong type safety. Instead of duplicating the same function or class for numbers, strings, arrays, or custom objects, you can define one generic version and let the caller decide what type to use.

Generics make code more flexible without giving up clarity. They are essential in TypeScript, Swift, and many advanced Python libraries, especially when working with collections, utility functions, or strongly typed APIs.


What Generics Solve

In traditional programming, you often run into situations where you want the same operation to work with multiple types. Without generics, you might have to write:

  • one function for numbers
  • another for strings
  • another for objects
  • another for custom models

Generics offer a single solution: choose the type later.

They help you:

  • avoid code duplication
  • catch mistakes before runtime
  • write safer APIs
  • build reusable data structures
  • improve readability of complex operations

Generics in TypeScript

TypeScript provides first-class generic support.

A generic is declared using angle brackets: <T>.


Generic Function in TypeScript

function wrap<T>(value: T): T[] {
  return [value];
}

const one = wrap(5);            // inferred as number[]
const nameList = wrap("Kai");   // inferred as string[]

The <T> means: “Treat T as a placeholder for the actual type.”

The caller decides whether T is a number, string, object, or anything else.

This keeps the function flexible while still type-safe.


Generic Interface in TypeScript

interface ApiResponse<T> {
  data: T;
  status: number;
}

const response: ApiResponse<{ message: string }> = {
  data: { message: "Success!" },
  status: 200,
};

Generics let you shape API responses without losing information about the actual data inside them.


Generic Class in TypeScript

class Box<T> {
  constructor(public item: T) {}
}

const stringBox = new Box("Hello");
const numberBox = new Box(42);

Each instance chooses its own type for T, keeping the class reusable.


Generics in Swift

Swift also supports generics extensively.

The syntax uses angle brackets and works similarly to TypeScript.


Generic Swift Function

func duplicate<T>(_ value: T) -> [T] {
    return [value, value]
}

let ints = duplicate(3)        // [3, 3]
let words = duplicate("sky")   // ["sky", "sky"]

Swift infers the type of T from the argument.

This keeps the function concise and reusable.


Generic Swift Struct

struct Pair<T> {
    let first: T
    let second: T
}

let coord = Pair(first: 10.2, second: 20.8)
let labels = Pair(first: "top", second: "bottom")

A single struct works for geometry, UI labels, or anything else that comes in pairs.


Generics in Python (Type Hints)

Python doesn’t enforce generics at runtime, but type hints allow you to use generic concepts with static type checkers like mypy or PyCharm.


Python TypeVar Example

from typing import TypeVar, List

T = TypeVar("T")

def repeat(item: T, times: int) -> List[T]:
    return [item] * times

vals = repeat("seed", 3)   # inferred as List[str]

Even though Python is dynamic, using TypeVar improves editor support and catches mistakes before they turn into bugs.


Python Generic Classes

from typing import Generic, TypeVar

T = TypeVar("T")

class Container(Generic[T]):
    def __init__(self, item: T):
        self.item = item

Tools can now track the type carried by each Container instance.


Why Generics Matter

Generics become essential in larger projects because they:

  • prevent accidental type mixing
  • make code more explicit and predictable
  • simplify maintenance
  • improve tooling (autocomplete, refactor safety, linting)
  • reduce repeated implementations

For example, an API client, a UI component library, or a data-processing pipeline can all use generics to keep their logic flexible and safe.


Real-World Examples

Here are real scenarios showing how generics improve structure and safety.


Example 1: Pagination Response (TypeScript)

interface Page<T> {
  items: T[];
  total: number;
}

const pageOfArticles: Page<{ title: string }> = {
  items: [{ title: "Intro to SQL" }],
  total: 1,
};

A single Page interface now works for articles, products, users, or any custom type.


Example 2: Swift Networking Result

struct Result<T> {
    let value: T
    let success: Bool
}

let temperature = Result(value: 22.5, success: true)

This single struct can wrap an integer, a user model, an array of messages — anything the API returns.


Example 3: Python Cache for Any Type

from typing import Dict, TypeVar

T = TypeVar("T")
Cache = Dict[str, T]

users_cache: Cache[dict] = {"u1": {"name": "Mira"}}
temp_cache: Cache[float] = {"today": 21.8}

One generic alias becomes two different cache types depending on usage.


Generic Constraints

Sometimes you need generics to only work with certain kinds of types.


TypeScript Constraints

function lengthOf<T extends { length: number }>(value: T) {
  return value.length;
}

lengthOf("cloud"); // 5

T must have a length property — strings, arrays, and some objects qualify.


Swift Constraints

func areEqual<T: Equatable>(_ a: T, _ b: T) -> Bool {
    return a == b
}

Swift ensures only comparable types can be passed.


Constraints keep generics safe while still flexible.


Common Mistakes

Overusing Generics

Not every function needs to be generic. If a function only ever works with numbers, using <T> makes the code harder to read.

Forgetting Constraints

Without constraints, generics may appear too permissive. Adding limits clarifies the expected shape of data.

Treating Python generics as enforced

Python’s generics are for analysis—not runtime enforcement. They guide developers and tools, not program execution.

Collapsing multiple types into “any”

When developers use any in TypeScript or broad constraints, they sacrifice the benefits generics provide.


Summary

Generics (or templates) let you build reusable code that adapts to different data types while still staying type-safe. TypeScript and Swift have full generic support, while Python adopts generics through type hints. They allow a single function, class, or interface to work across many kinds of values, making complex systems easier to scale and maintain. Once you become comfortable with generics, you can design cleaner APIs, more flexible utilities, and models that grow with your application.

Learn to Code for Free
Start learning now
button icon
To advance beyond this tutorial and learn to code by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

Reach your coding goals faster