An example without generics

The most straightforward examples are lists and arrays—two incredibly useful data structures that you'll find in most programming languages. Generally speaking, you do not want to have to reimplement such data structures for each specific data type. Instead, you want to have a single, canonical, and generic implementation that can work with different types.

In TypeScript, we can use the any keyword as a type to allows us to pass any type to our functions. However, as we have just mentioned, this would imply having to use type casts all the time, which is far from convenient.

any is actually the type that is used by default in TypeScript when no type is specified for a variable or function argument.

Let's imagine what the Array interface would look like if it used any:

interface Array { 
    ...​ 
    push(...​items: any[]): number; 
    ...​ 
    pop(): any; 
    ...​ 
} 

This interface is OK for JavaScript, but it is far from ideal in TypeScript. This is because it forces us to use type casts all the time when accessing data, as shown in the following example:

const myArray: any[] = []; 
myArray.push(new Person("John", "Doe")); 
const person: Person = <Person> myArray.pop(); 

Of course, this works, but it means a lot of added ceremony around data retrieval. In addition, this code is unsafe because you have no guarantees that what you get out of the array will be of the type you expect when performing the type cast.