TypeScript Advance APIs
1. Pick
We know Types and Interfaces in Typescript so far. Both works similar providing the structure for our objects. However, Interfaces has additional flexibility of extending other interfaces.
interface User {
name: string;
age: number;
}
function sumOfAges(user1: User, user2: User): number {
return user1.age + user2.age;
}
const user1: User = {
name: "Aniket",
age: 23,
};
const user2: User = {
name: "Virat",
age: 36,
};
const sum = sumOfAges(user1, user2);
console.log(sum);
If we want to update some information of the user let’s say - ‘name’, ‘email’, and ‘age’ then we can write a function that accepts these 3 arguments and make a db call to update the user. This is one of the solutions. Or we can create another interface that takes only the properties to be updated and pass it to the function. It will do the work.
Sol 1:
interface User {
id: number;
name: string;
age: number;
email: string;
password: string;
}
function updateUser(name: string, age: number, email: string) {
// db call to update the user
}
Sol 2:
interface User {
id: number;
name: string;
age: number;
email: string;
password: string;
}
interface UpdateProps {
name: string;
age: number;
email: string;
}
function updateUser(updatedProps: UpdateProps) {
// db call to update the user
}
But here the one problem we can face is - if we want to change the type of age from number to string, then we would have to change it from both the places. Assume our codes get bigger & bigger then this will really be a headache. To make this easier we have an API called Pick.
Instead of this we can use the Pick API. It allow us to create a new type by selecting a set of properties from the existing type/interface. It takes two arguments -
Where to pick from
What to pick
Sol 3:
interface User {
id: number;
name: string;
age: number;
email: string;
password: string;
}
type UpdateProps = Pick<User, 'name' | 'age' | 'email'>;
function updateUser(updatedProps: UpdateProps) {
// db call to update the user
}
2. Partial
Partial make all the properties of a type / interface as optional. For example, we are taking ‘name’, ‘age’ and ‘email’ from the user to update it. But the user might not want to update all three of these. Maybe he wants to update only the email. In this case there is no point taking other properties i.e. ‘name’ and ‘age’ from the user.
Sol 1:
interface User {
id: number;
name: string;
age: number;
email: string;
password: string;
}
interface UpdateProps {
name?: string;
age?: number;
email?: string;
}
function updateUser(updatedProps: UpdateProps) {
// db call to update the user
}
Sol 2:
interface User {
id: number;
name: string;
age: number;
email: string;
password: string;
}
type UpdateProps = Pick<User, 'name' | 'age' | 'email'>;
type UpdatePropsOptional = Partial<UpdateProps>;
function updateUser(updatedProps: UpdatePropsOptional) {
// db call to update the user
}
updateUser({
email: "abcd@gmail.com"
// even if we provide all 3 properties, ts won't complain
})
3. Read Only
We have studied that if we declare any variable or object with const keyword then we cannot change it. Though, we change the internal values inside the variable (array/object) but we cannot change the reference of any variable which is declared with const keyword.
Example:
const arr = [1, 2, 3, 4];
arr[0] = 10; // this is acceptable
arr = [10, 20, 30] // this is wrong
But let’s say you want to make any property of (array, object, type, interface) read only (it cannot be changed once declared) then use readonly keyword.
interface User {
readonly name: string;
age: number;
}
const user: User = {
name :"harry",
age: 19
}
user.name = "potter"; // this will give an error
user.age = 21; // this is fine
console.log(user);
4. Record & Map
Record provides a cleaner way to declare objects in Typescript. Till now we have been declaring object like this which is not a cleaner syntax to read.
type Users = {
[key: string]: number
}
const users: Users = {
"user1": 1,
"user2": 2
}
console.log(users)
A better way to write object would be to use Record.
type Users = Record<string, number>
const users: Users = {
"user1": 1,
"user2": 2
}
console.log(users);
Map works to similar to how it works in any other programming languages like Java or C++ allowing us to store key-value pairs. In normal way declaring objects (like one written above), to get the value of the users object or to update users object we would have to write something like this:
users[”users1”] = 10;
Instead we can use Maps get use the predefined method like get(), set(), delete(), size(), etc.
const users = new Map();
users.set("id1", { id: 1, name: "aniket" });
users.set("id2", { id: 2, name: "kadale" });
console.log(users.get("id1"));const users = new Map(); users.set("id1", { id: 1, name: "aniket" }); users.set("id2", { id: 2, name: "kadale" }); console.log(users.get("id1"));
We can also enforce the Map to have specific types. i.e. <key: string, value: User>
type User = {
id: number;
name: string;
}
const users = new Map<string, User>();
users.set("id1", { id: 1, name: "aniket" });
users.set("id2", { id: 2, name: "kadale" });
console.log(users.("id1"));
5. Exclude
This is pretty much self-explanatory. Suppose you can certain values but wants to exclude some of the values from it.
type EventType = "scroll" | "click" | "mousemove";
type ExcludeEvent = Exclude<EventType, "mousemove">;
const handleEvent = (event: ExcludeEvent) => {
console.log(`Handling event: ${event}`);
};
handleEvent("scroll");
handleEvent("mousemove"); // this will give an error
These are some of the APIs in TypeScript that you might want to use in your applications!
Subscribe to my newsletter
Read articles from Aniket Kadale directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by