Type annotations (or type hints) are used to denote the data type of a given variable or function. In many languages, we either must explicitly annotate a variable with a type, or we may have the option not to.

Many modern programming languages (sans JavaScript) support the ability to add type annotations, including in dynamically typed languages like Python.

Adding type annotations should be instinctual behaviour for us, wherever possible.

Union type

If a value can be more than one type, we specify this with a union type, where we have a vertical pipe | separate the types in the annotation. This behaviour’s supported in Python and TypeScript. C, C++, and Rust support union types via a different mechanism.

Inferred types

In some programming languages, there are keywords (or a lack thereof) that allow the compiler or interpreter to deduce the correct type given an assignment expression. This usually doesn’t make it dynamically typed or easily switchable (if we’re using a statically typed language), but it does permit us to make our code a little cleaner.

In C-style languages, it also makes range-based for loops easier, i.e., for (auto i = 0; ...) or for (auto i: container_t).

Language support:

  • In C++11 onwards, the auto type does this.
  • In Java 10 onwards, the var type does this.
  • In Rust, rustc will automatically infer the type with let.