Types in TypeScript
Published: 2023-02-21 20:12:08

TypeScript is a superset of JavaScript that introduces types to the language. Types are a way of defining the data that a variable can hold. They provide a way of catching errors early and making code more reliable. In this article, we will take a deep dive into the type system in TypeScript, including number, string, boolean, and union types.

**Basic Types**

In TypeScript, there are several basic types that can be used to define variables. These types include:

number: represents any numeric value, including integers and floating-point numbers.

string: represents any text value, including strings of characters and numbers.

boolean: represents a value that is either true or false.
any: represents any type of value.

To define a variable with a specific type, we use a colon followed by the type name. For example, to define a variable of type number, we can do:


```typescript
let myNumber: number = 42;
```

This variable can only hold numeric values. If we try to assign a non-numeric value to it, TypeScript will give us an error.

**Union Types**

Union types allow us to define a variable that can hold more than one type of value. We use the vertical bar (|) to separate the types. For example, to define a variable that can hold either a string or a number, we can do:


```typescript
let myVar: string | number;
```

Now we can assign a string or a number to this variable. If we try to assign any other type of value, TypeScript will give us an error.

**Type Inference**

TypeScript has a feature called type inference, which means that TypeScript can sometimes figure out the type of a variable based on its initial value. For example, if we define a variable and assign it the value 42, TypeScript will infer that the variable is of type number:

```typescript
let myNumber = 42; // TypeScript infers that myNumber is of type number
```

This can save us some typing, but we should still be explicit about the types of our variables whenever possible.

**Functions and Types**

Functions in TypeScript can also have types. The type of a function specifies the types of its parameters and return value. For example, to define a function that takes two numbers and returns a number, we can do:


```typescript
function addNumbers(a: number, b: number): number {
  return a + b;
}
```

Here, we specify that the function takes two parameters, both of type number, and returns a value of type number. If we try to call this function with non-numeric parameters or expect it to return a non-numeric value, TypeScript will give us an error.

**Interfaces**

Interfaces are a way of defining the shape of an object. They allow us to specify the names and types of the properties that an object must have. For example, to define an interface for a person object, we can do:


```typescript
interface Person {
  name: string;
  age: number;
  email: string;
}
```

Now we can define a variable of type Person and assign it an object with the required properties:


```typescript
let person: Person = {
  name: "John",
  age: 30,
  email: "john@example.com"
};
```

If we try to assign an object that does not have the required properties, TypeScript will give us an error.

**Classes**

A class is a blueprint for creating objects with a set of properties and methods. In TypeScript, classes can be defined using the class keyword, and can include properties, methods, and a constructor function.

Here is an example of a class definition in TypeScript:


```typescript
class Animal {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  speak() {
    console.log(`${this.name} says hello!`);
  }
}

let dog = new Animal("Fido", 3);
dog.speak(); // output: "Fido says hello!"
```

In this example, we define a Animal class with name and age properties, a constructor function that sets the name and age properties, and a speak method that logs a message to the console.

We then create a new instance of the Animal class and call the speak method on it.


**Interfaces**


An interface is a contract that defines the shape of an object. It defines a set of properties and their types, but does not provide an implementation.

Here is an example of an interface definition in TypeScript:


```typescript
interface Person {
  name: string;
  age: number;
  address?: string;
}

let john: Person = { name: "John", age: 30 };
let jane: Person = { name: "Jane", age: 25, address: "123 Main St" };

```

In this example, we define a Person interface with name and age properties, and an optional address property.

We then create two objects that conform to the Person interface, one with just a name and age property, and the other with all three properties.

Interfaces can be used to ensure that objects passed to functions or returned from functions conform to a certain shape, which can help catch errors at compile time.

**Generics**

Generics are a way to create reusable components in TypeScript that can work with a variety of types. They allow us to define functions, classes, and interfaces that can work with any type.

Here is an example of a generic function in TypeScript:


```typescript
function identity<T>(arg: T): T {
  return arg;
}

let result1 = identity<string>("hello");
let result2 = identity<number>(42);
```

In this example, we define a identity function that takes a generic type parameter T and returns an argument of type T. We then call the identity function with a string argument and a number argument, providing the type parameter explicitly.

Generics can also be used with classes and interfaces to create reusable components that can work with a variety of types.

**Conclusion**

In this article, we have covered the basics of TypeScript's type system, including primitive types, unions, classes, interfaces, and generics.

By using TypeScript's powerful type system, we can catch errors at compile time and write more reliable and maintainable code.