Programming Languages

Type Systems

The rules a language uses to classify values and reject nonsense: static or dynamic, nominal or structural, with or without inference.

Level: intermediate

What is it?

A type system classifies values and decides which operations are legal on them. Static typing checks before the program runs (Java, C, TypeScript); dynamic typing checks as operations execute (Python, JavaScript). Nominal typing compares by declared name; structural typing compares by shape. Inference lets the compiler work out types you did not write, and generics let one definition work over many types.

Why does it matter?

The type system decides which bugs you find at compile time and which in production, how much your editor can help, and how safely you can refactor. It also shapes how a language feels: strictness and ceremony against flexibility and speed of sketching.

Mental model

Airport security for values. A static checker inspects the bag before the flight (compile time). A dynamic checker inspects at the gate, when you are already about to board (run time). Either way, the goal is to stop the wrong thing getting on the plane.

How it works

  • Static: types checked before running; errors show up early and tools get smarter. Dynamic: types checked at run time; less ceremony, later errors.
  • Strong versus weak describes how freely values convert: Python refuses '1' + 1, while JavaScript quietly returns '11'.
  • Nominal: two types are compatible only if declared so (Java interfaces). Structural: compatible if they have the right members (TypeScript, Go interfaces).
  • Inference: 'let n = 3' is an int without writing it, though the type is still fixed.
  • Generics (List<T>) let one implementation be type-safe for any element type.
  • Optional and gradual typing (Python hints, TypeScript) adds static checks to a dynamic ecosystem. Types can be erased before running, so they guard the code, not the data that arrives at run time.

Steps

  • Declare or infer a type
  • Check each operation
  • Reject a mismatch
  • Erase or keep types at run time

Code example: Structural typing catches a bad call before it runs

type Point = { x: number; y: number };

function norm(p: Point): number {
  return Math.sqrt(p.x * p.x + p.y * p.y);
}

const a = { x: 3, y: 4, label: "A" };   // extra fields are fine: the shape matches
console.log(norm(a));                    // 5
// norm({ x: "3", y: 4 });               // compile error: string is not number

Real-world usage

  • Choosing a language for a large team codebase versus a quick script
  • Modeling data so invalid states cannot be represented
  • Refactoring with the compiler pointing at every call site

Common mistakes

  • Believing static types validate data that arrives from a network or file; they do not.
  • Turning types off (any, casts) whenever they are inconvenient.
  • Equating 'dynamic' with 'untyped' — values still have types; the checks just happen later.

Interview questions

What is the difference between static and dynamic typing?

Static typing checks types before the program runs, so many errors surface at compile time. Dynamic typing checks as operations execute, so the same mistakes appear only when that line runs.

What is duck typing?

An object is acceptable if it has the methods or fields the code uses, regardless of its declared class. 'If it walks like a duck and quacks like a duck…' It is a dynamic form of structural typing.

Why does TypeScript not protect you from bad JSON at run time?

Its types are erased when compiled to JavaScript, so nothing checks the actual data. Validate untrusted input at the boundary, for example with a schema library, and then trust the types.

LanguageCheckingConversionsCompatibility
PythonDynamic (optional hints)Strict: no implicit str/int mixDuck typing
JavaScriptDynamicLoose: heavy coercionBy shape at run time
JavaStaticStrictNominal
TypeScriptStatic, erased at run timeStrict to the checkerStructural
CStaticLoose: casts and void*By declared type

Prerequisites

Related concepts

Continue learning

Browse the full computer science library