Mapped Type Modifiers

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional TypeScript Masterclass Lessons

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11

Mapped Type Modifiers

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Nature of Properties

Properties can be readonly or optional (?) e.g.:

export type Point = {
readonly x: number,
y?: number,
};

Unit Mapped Type

The following mapped type makes no changes to the input type:

export type Mapped<T> = {
[P in keyof T]: T[P]
};

readonly Modifier

Modifiers can be used to make properties readonly e.g.:

export type Mapped<T> = {
readonly [P in keyof T]: T[P]
};

+ is explicit but can also be provided explicitly e.g.:

export type Mapped<T> = {
+readonly [P in keyof T]: T[P]
};

- can be provided to make properties writable e.g.:

export type Mapped<T> = {
-readonly [P in keyof T]: T[P]
};

Optional ? Modifier

? can be added to make properties optional e.g.:

export type Mapped<T> = {
[P in keyof T]?: T[P]
};

+ is explicit but can be added explicitly e.g.:

export type Mapped<T> = {
[P in keyof T]+?: T[P]
};

- can be provided to make properties required e.g.:

export type Mapped<T> = {
[P in keyof T]-?: T[P]
};

Combining Modifiers

Modifiers can be combined to make multiple changes in a single go, e.g. making properties readonly and required (-?):

export type Mapped<T> = {
+readonly [P in keyof T]-?: T[P]
};

Use Case

You can create pretty powerful functions, e.g. creating a partially updating State class:

export type Partial<T> = {
[P in keyof T]?: T[P]
}

export class State<T> {
constructor(public current: T) { }
update(next: Partial<T>) {
this.current = { ...this.current, ...next };
}
}

state.update({ y: 123 }); // Update `y` only

Further

The definition we have built for Partial<T> is actually built in to TypeScript so you don't need to create it yourself.

javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

Here we have a type with properties of mixed modifiers. We have type X as read only and type Y as optional. To demonstrate the usage of map type modifiers, we create this utility map type that does nothing other than map over the properties in T and simply map them out to whatever they are within the type T. So if we use this utility type on the type point, the output would be the same as the input that is the same two members X as read only and Y as optional. Now, we've already looked at how we can make the properties

00:34

as read only in the output type by using the read only modifier. This makes all the properties as read only, and you can see that Y has become read only in the output type. TypeScript also allows you to optionally add the plus sign before the read only modifier. The output will be the same as without the plus token, but it might help you read better. TypeScript also allows you to add the optional nature in the generated properties by using the question mark token. And now if you look at the generated type, you can see that X has become optional in the output results.

01:08

Now, just like the read only modifier, you can add a plus before the question mark token if it helps you read better. I personally do not use these plus tokens. However, the reason why they're supported is that you can actually use a minus token to remove the optional nature or the read only nature. So if you use minus question mark, you can see that the optional nature of Y is removed in the generated type. Similarly, if you use minus read, only the read only nature of X will be removed in the generated type. Now to get more experience with map type modifiers,

01:42

let's look at a use case. Here we have a class designed to manage some state. It takes an initial state and stores it in its current property, and a method update to update the current value with the next state object that is passed in, we can create a new state object with members X and Y initialized to zero. This makes type T for the state instance as X and Y of type number. So we can update the state to a new X and Y value by passing an object to the update method. And indeed this does update the current

02:16

state with the correct values. However, notice the implementation of the update method. If we provide an object that doesn't have all the members that are required by Type T, it does automatically fill them from the current object. So we should be able to provide just the members that we want to update. However, this results in a compile time error because next has been annotated to accept the full type T, and we are not providing the X member anymore. The solution to this problem is to generate a type such that it has the same members as type T,

02:50

but all of them are marked optional. Now we can create a utility type function called partial that simply maps over an input type T and Adds the question mark modifier to all of the members. And now we can annotate the next argument for the update function to be a partial of type T. With this type annotation in place, the error on the update call goes away. Now creating a partial for any given input type is actually a common enough use case that we don't have to code up this particular utility type ourself. If we go ahead and delete our implementation, it falls back

03:24

to a built-in implementation provided by the TypeScript compiler that achieves the same purpose. And if you hover over the type, you can see that it is implemented by the TypeScript team exactly how we wrote it right now.

Professional TypeScript Masterclass

Professional TypeScript Masterclass

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11