Duck typing

TypeScript also uses a method called duck typing for more complex variable types. Duck typing suggests that if it looks like a duck, and walks like a duck, then it probably is a duck. In other words, two variables are considered equal if they have the same properties and methods, as they can be exchanged for one another, but will still provide the same behavior. Consider the following TypeScript code:

var complexType = { name: "myName", id: 1 }; 
complexType = { id: 2, name: "anotherName" };

We start with a variable named complexType that has been assigned a simple JavaScript object with a name and id property. On our second line of code, we are reassigning the value of this complexType variable to another object that also has an id and a name property. The compiler will use duck typing in this instance to figure out whether this assignment is valid. In other words, if an object has the same set of properties as another object, then they are considered to be of the same type.

To further illustrate this point, let's see how the compiler reacts if we attempt to assign an object to our complexType variable that does not conform to this duck typing:

var complexType = { name: "myName", id: 1 }; 
complexType = { id: 2 }; 

Here, the first line of this code snippet defines our complexType variable and assigns to it an object that contains both an id and name property. From this point on, TypeScript will use this inferred type for the complexType variable. On our second line of code, we are attempting to reassign the complexType variable to a value that only has an id property and not the name property. This line of code will generate the following compilation error:

error TS2322: Type '{ id: number; }' is not assignable to type '{ name: string; id: number; }'.

Property 'name' is missing in type '{ id: number; }'.

The error message is pretty self-explanatory. In this instance, TypeScript is using duck typing to ensure type safety. As the complexType variable has both an id and a name property, any object that is assigned to it must also have both an id and a name property.

Note that the following code will also generate an error message:

var complexType = { name: "myName", id: 1 }; 
complexType = { name : "extraproperty", id : 2, extraProp: true };

The error generated here is as follows:

error TS2322: Type '{ name: string; id: number; 
extraProp: boolean; }' is not assignable to type '{ name: string; id: number; }'.

Object literal may only specify known properties, and 'extraProp' does not exist in type '{ name: string; id: number; }'.

As can be seen in this error message, the complexType variable does not have an extraProp property, and therefore the assignment fails.

Inferred typing and duck typing are powerful features of the TypeScript language, bringing strong typing to variables that are made up of many properties, all without the need to use explicit typing.