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
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.
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:
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
.
// 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:
// 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",
}
Intersection in `type`
You can combine two or more types using &
. You can do that as shown in the following code:
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
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
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:
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:
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:
// ✅ 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:
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:
// 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:
// ❌ 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
Top comments (2)
Nice article!
I think there is an error in the example you wrote on the Union in Functions section, it should be
Thanks man for catching this, it was a typo error. 👐