Please do not link to this article on Reddit or Hacker News.

An important attribute of every type system is whether they are structural or nominal, they can even be mixed within a single type system. So it’s important to know the difference.

A type is something like a string, a boolean, an object, or a class. They have names and they have structures. Primitives like strings or booleans have a very simple structure and only go by one name.

More complex types like object or classes have more complex structures. They each get their own name even if they sometimes have the same structure overall.

A static type checker uses either the names or the structure of the types in order to compare them against other types. Checking against the name is nominal typing and checking against the structure is structural typing.

Nominal typing

Languages like C++, Java, and Swift have primarily nominal type systems.

class Foo {

method(input: string): number { ... }

} class Bar {

method(input: string): number { ... }

} let foo: Foo = new Bar(); // ERROR!!

Here you can see a pseudo-example of a nominal type system erroring out when you’re trying to put a Bar where a Foo is required because they have different names.

Structural typing

Languages like OCaml, Haskell, and Elm have primarily structural type systems.

class Foo {

method(input: string): number { ... }

} class Bar {

method(input: string): number { ... }

} let foo: Foo = new Bar(); // Okay.

Here you can see a pseudo-example of a structural type system passing when you’re trying to put a Bar where a Foo is required because their structure is exactly the same.

However, as soon as you change the shape it will start to cause errors.