Learning TypeScript 2.x
上QQ阅读APP看书,第一时间看更新

Structural type system

In the type system of a programming language, a type is an object with a name and a structure. Some types have very simple data structures (such as primitives) while others use complex structures (such as classes).

The type system can use two different strategies to validate that a given value matches the desired type:

  • Nominal type system: In this type system, values are matched against a type by its name
  • Structural type system: In this type system, values are matched against a type by its structure

The TypeScript type system is a structural type system because the values are matched against a type by its structure, as the following code snippet demonstrates:

interface Person {
name: string; surname: string; } function getFullName(person: Person) { return `${person.name} ${person.surname}`; } class Employer { constructor( public name: string, public surname: string ) {} } getFullName(new Employer("remo", "jansen")); // OK const p1 = { name: "remo", surname: "jansen" }; getFullName(p1); // OK const p2 = { name: "remo", familyName: "jansen" }; getFullName(p2); // Error

In the preceding code snippet, we can observe how the first two calls to the getFullName function are successful because the structure (properties and types) of both the Employer instance and the object literal match the structure of the Person interface.

The following code snippet showcases how TypeScript would work if it used a nominal type system:

interface Person {
name: string;
surname: string;
}

function getFullName(person: Person) {
return `${person.name} ${person.surname}`;
}


class Employer implements Person { // Named!
constructor(
public name: string,
public surname: string
) {}
}


getFullName(new Employer("remo", "jansen")); // OK


const p1: Person = { name: "remo", surname: "jansen" }; // Named!
getFullName(p1); // OK


const p2: Person = { name: "remo", familyName: "jansen" }; // Error
getFullName(p2); // OK

The first call to getFullName works because the Employer class implements the Person interface, and the name of the type of the interface can then be matched against the name of the type of the function argument.

The TypeScript team is currently investigating the possibility of potentially adding support for a nominal type system as well. You can learn more about the progress at https://github.com/Microsoft/TypeScript/issues/202 .