Typescript - Tips & Tricks - Mapped Types

Full Stack Developer and JavaScript and TypeScript enthusiastic.
Search for a command to run...

Full Stack Developer and JavaScript and TypeScript enthusiastic.
No comments yet. Be the first to comment.
In this series, You'll see some tips and tricks using Typescript
Hi Guys, Today I'll show you some advanced utilities exposed by the typescript language. Let's start! Utilities for Types Partial This utility allows you to add the optional modifier to all the properties of your type. type PartialPoint = Partial<{...
Today, I wanna show you how to set up your devices with Antigravity using only the agentic mode, without touching any code. At the last CodeMotion Rome, I got my special badge. A CM Node, a special ha

As a developer, you have to take control of your projects every day. Whether it is a company repository, an open source project you maintain or collaborate on, or a simple pet project. Gaining control over your projects often depends on the platform ...

My Antigravity first experience

Write clear and insightful commit messages using AI and GitLens.

We are in the AI era. New models emerge daily, and many applications have already integrated AI into their workflows. Gemini, OpenAI, Copilot, Deepseek, Llama, and many others enable AI in your applications or help you write code, but they all need a...

In some cases, we need to manipulate some types to create new types. In these cases, we have to use the Mapped Types. Let's start explaining the structure of the mapped types.
type MappedTypeExample = {
[Key in "x" | "y" | "z"]: number;
};
As you can see, a mapped type is a type composed of defined keys and their values, but the power of the mapped types goes out when we want to joke with a generic type.
type Point = {
readonly x: number;
y: number;
z?: number;
};
type MappedType<T> = {
[K in keyof T]: T[K];
};
type mappedPoint = MappedType<Point>;
/**
type mappedPoint = {
readonly x: number;
y: number;
z?: number | undefined;
}
*/
In this simple example, I show you how to replicate the same object using the mapped type. Now let's add two simple bits to transform our type into new "different" types. The mapped type permits you to add(+) or remove(-) the read-only modifier from your type but also to add(+) or remove(-) the optional modifier. I leave you two simple examples to show these cases.
type MappedPointPlusModifier<T> = {
+readonly [K in keyof T]: T[K];
};
type mappedPointPlusModifier = MappedPointPlusModifier<Point>;
/**
type mappedPointPlusModifier = {
readonly x: number;
readonly y: number;
readonly z?: number | undefined;
}
*/
type MappedPointMinusModifier<T> = {
[K in keyof T]-?: T[K];
};
type mappedPointMinusModifier = MappedPointMinusModifier<Point>;
/**
type mappedPointMinusModifier = {
readonly x: number;
y: number;
z: number;
}
*/
N.B. The add(+) modifier isn't indicated in common cases because it is implied
The mapped types are a powerful feature to manipulate our types and they are used by the typescript team to expose to us some advanced types, but this is a topic of a future post. Before ending I leave you another example to show what you can do with the mapped type. In this example, I transform the Point type to another Point type where the fields aren't exposed directly but they are wrapped by a "get" and "set" method.
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type Setters<T> = {
[K in keyof T as `set${Capitalize<string & K>}`]: (value: T[K]) => void;
};
type WithGetterAndSetter<T> = Getters<T> & Setters<T>;
type Point = {
x: number;
y: number;
};
type WithGetterAndSetterPoint = WithGetterAndSetter<Point>;
/**
type WithGetterAndSetterPoint = {
getX(): number;
setX(value: number): void;
getY(): number;
setY(value: number): void;
}
*/
It's all for today! See you soon guy!