Typescript: Type Aliases and Union
Tags: typescript, webdev, beginners, tutorial
Published: 2023-01-24 12:30:00

In this article, you will learn about Type Aliases and how you can define your own types in typescript and use that in functions or classes as well. Along with Type Aliases, I have also explained how you can use Union to create multiple type variables which means that one variable can have multiple types at once.

> This is going to be a full series of typescript where you will learn from basic topics like string, boolean to more complex like Type Aliases, enums, Interface, generics, etc.

### Table of Contents
{%- # TOC start -%}
- [Type Aliases](#type-aliases)
  * [Readonly and Optional](#readonly-and-optional)
  * [Intersection in `type`](#intersection-in-type)
  * [Type Aliases in Functions](#type-aliases-in-functions)
- [Union](#union)
  * [Union in Functions](#union-in-functions)
  * [Union in Array](#union-in-array)
  * [Special Case for Union](#special-case-for-union)
{%- # TOC end -%}


## Type Aliases

We can use the objects as shown in the previous example but what if there are 100s of functions that need the same data of the user then you'll be typing for all of them separately that's where **Type** comes into play. Let's look at the old example and how we can use `type` to make it reusable.

```ts
type User = {
  email: string;
  password: string;
};

// ✅ CORRECT
// Passsing Object Type Aliases
function signUp(user: User){}

// ✅ It's the correct way to call
signUp({email: "some@hello.com", password: "1233"})

// ❌ ERROR : 'name' does not exist in type 'User'
signUp({email: "some@hello.com", password: "1233", name: "Sam"})

// ✅ You can pass extra information by using a variable
let userObj =  {email:  "some@hello.com", password:  "1233", name:  "Sam"}
signUp(userObj)
```

You can use a type alias to give a name to any type at all, not just an object type. For example:

```ts
type ID = number;
let userId: ID = 111; // ✅ CORRECT
```

I guess you get the point that we use `type` to define the actual type of the variable. It can be used anywhere.

### Readonly and Optional

**readonly** means that the user or anyone cannot manipulate that variable, for example `id` **optional** means that these parameters are optional which we have looked at before in functions.

Let's take an example of `User` where the user will have three properties `id`, `email`, and `name`.

```typescript
// Defining the User type
type User = {
	readonly id : string,
	name: string,
	email: string,
}

// Now Let's create a user variable using the above type:
let myUser:User = {
	id : "3947394",
	name: "harry",
	email: "h@harry.com",
}

// Now I'll assign the values to the myUser object

// ✅ CORRECT
myUser.name = "Potter";
myUser.email = "hello@harry.com";

// ❌ ERROR: Cannot assign to 'id' because it is a read-only property
myUser.id = "121324";
```

Now, let's take a look at the optional:

```ts
// Defining the User type
type User = {
	readonly id : string,
	name: string,
	email: string,
	dob?: string 	// optional
}

// ✅ CORRECT
let user1: User = {
	id : "3947394",
	name: "harry",
	email: "h@harry.com",
	dob: "02/12/1998"
}

// ✅ CORRECT
let user2: User = {
	id : "3947394",
	name: "harry",
	email: "h@harry.com",
}
```

<h3 id="intersection-in-type">Intersection in `type` </h3>

You can combine two or more types using `&`. You can do that as shown in the following code:

```typescript
type User = {
	readonly id : string,
	name: string,
	email: string,
}

type Admin = User & {
	key: string, 
}

// You can use Admin like this:
let newAdmin: Admin = {
  id: "3KD5D874",
  name: "Lucifer",
  email: "lucifer@hell.com",
  key: "Oh my me!",
};
```

Now `Admin` will have `User` properties as well as shown in the above code.

### Type Aliases in Functions

As I have defined multiple types in the above code. These are the custom type that you can even use in functions in form of Parameters or Return Values. You just need to define the `type` and then pass it as the parameter.

**Type Aliases as a function parameter**

```typescript
 type User = {
    name: string,
	email: string,
    password: string, 
}
// You can use optional variables as well 

// Function that will add user to the database
function addUser(user: User){
    // do some database opertion
}


// ❌ ERROR:  Property 'password' is missing in type '{ name: string; email: string; }' but required in type 'User'
addUser({name: "Rao", email: "rao@gmail.com")
// ✅ CORRECT
addUser({name: "Rao", email: "rao@gmail.com", password: "12345678"})
```

**Type Aliases as a function return value**

```typescript
type User = {
    _id: string 
    name: string,
	email: string,
}

// ✅ CORRECT
function loginUser(id: string): User {
    // performing some operation
    return {_id: id, name: "Joe", email:"joe@gmail.com"}
}

// ❌ ERROR: Property 'email' is missing
function loginUser(id: string): User {
    // performing some operation
    return {_id: id, name: "Joe"}
}
```

## Union

In Typescript, you can define more than one type of variable. You can do that by just putting (`|`) in the middle of two types. Let me show you what I am saying:

```ts
let id: string | number;

id = 123;		 	// ✅
id = "34398493";	// ✅
```

Both the example shown in the above code is correct. Let's take a little more complex example to understand how it works:

```ts
type User = {
	name: string,
	id : number
}

type Admin ={
	username: string,
	id: number,
	key: number,
}

let newUser : User | Admin;

// ✅ CORRECT
newUser = {name: "John", id: 123};
newUser = {username : "j333", id : 123, key: 345};
newUser = {name: "j333", id : 123, key: 345};

// ❌ ERROR: Property 'key' is missing
newUser = {username : "j333", id : 123};
```

### Union in Functions

You can also use these with function parameters as shown below:

```ts
// ✅ It works and id have string and number type
function setUserId(id: string | number){
	console.log(id);
}

// ❌ ERROR : 
// What if we do like this:
function setUserId(id: string | number ){
	id.toLowerCase()  // ❌ ERROR: Property 'toLowerCase' does not exist on type 'number
}
```

Now the above code will show you an error because `id` has two types `string` and `number.` The string can be converted to lowercase but the number can't. That's why it is showing you the error. You can use the conditional statement to do your desired stuff. Such as:

```ts
function setUserId(id: string | number ){
	if (typeof id === "string") {
		id.toLowerCase()
	}
	// do other things
}
```

Now it won't give you any errors because we are making sure that `toLowerCase()` only calls when the `id` is a string.

### Union in Array

In the array section, we discussed that we can set an array type with two methods. But the issue with that is What if we want an array that has multiple types of values such as `string` and `number` then what do we do? The answer is Union. Now let's take a look at how you do it:

```ts
// You might be thinking like this
// Nah ❌ you can't do like that
let newArray: number[] | string[] = [1,2, "hello"];

// ✅ Correct way to define the array with multiple type is:
let newArray: (number | string)[] = [1,2, "hello"];
```

### Special Case for Union

Now imagine you are working on CSS Framework and you are designing a `Button`. And you are asking the user to tell what size should button have. Now you can use the variable type as `string` but the user can type anything, right? Let's understand this via an example:

```ts
// ❌ WRONG APPROACH
let ButtonSize: string;

ButtonSize = "big";
ButtonSize = "medium";
ButtonSize = "don't know";  // that's why don't use this

// ✅ CORRECT APPROACH
let ButtonSize : "sm" | "md" | "lg" | "xl";

ButtonSize = "sm";
ButtonSize = "md";
ButtonSize = "lg";
ButtonSize = "xl";

// ❌ ERROR: Type 'large' is not assignable to type
ButtonSize = "large";
```

As you saw at the end of the above code the typescript restricts you from assigning `large` to `ButtonSize`. It only accepts special types defined by you for the button.

## Your Task

Now, It's your turn to create something. So, for that You have to create a type for a User that will have the following properties:

* **\_id**: a string representing a unique identifier for the user
    
* **name**: a string representing the user's name
    
* **posts**: an array of objects, each representing a post made by the user, with properties id, title, and body
    
* **comments**: an array of objects, each representing a comment made by the user, with properties id, postId, and body.
    

### Wrapping up

In this article, I explained what is Type Aliases and how you can define your own types in typescript and use that in functions or classes as well. Along with Type Aliases, I have also explained how you can use Union to create multiple type variables which means that one variable can have multiple types at once.

This is a series of Typescript that will help you to learn Typescript from the scratch. If you enjoyed this article, then don't forget to give ❤️ and Bookmark 🏷️for later use and if you have any questions or feedback then don't hesitate to drop them in the comments below. I'll see in the next one.

**Connect with me**

|Twitter |GitHub  | LinkedIn | Instagram | Website| Newsletter| Support |
|--|--|--|--|--|--|--|
| [![](https://cdn-icons-png.flaticon.com/32/4494/4494477.png)](https://twitter.com/j471n_) |[![](https://cdn-icons-png.flaticon.com/32/2504/2504911.png)](https://github.com/j471n) |  [![](https://cdn-icons-png.flaticon.com/32/3536/3536505.png)](https://www.linkedin.com/in/j471n/)|[![](https://cdn-icons-png.flaticon.com/32/174/174855.png)](https://instagram.com/j471n_)| [![](https://cdn-icons-png.flaticon.com/32/3178/3178285.png)](https://j471n.in)| [![](https://cdn-icons-png.flaticon.com/32/5822/5822078.png)](https://j471n.substack.com/) | [![](https://cdn-icons-png.flaticon.com/32/2935/2935413.png)](https://www.buymeacoffee.com/j471n)|