ThisType<T>

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

ThisType<T>

Subscription Required

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

Recap this Parameter Annotation

Something we covered in our lesson on this parameter:

type Math = {
double(): void,
half(): void,
}

export const math: Math = {
double(this: { value: number }) {
this.value *= 2;
},
half(this: { value: number }) {
this.value /= 2;
}
}

const obj = {
value: 1,
...math,
};

obj.double();
console.log(obj.value); // 2

obj.half();
console.log(obj.value); // 1

Notice the duplication of this: { value: number } for every function

Using ThisType

With ThisType<T> we can remove the duplication of this: { value: number } and declare it as a part of the Math type:

type Math = {
double(): void,
half(): void,
} & ThisType<{ value: number }>

export const math: Math = {
double() {
this.value *= 2;
},
half() {
this.value /= 2;
}
}

Advanced Example

ThisType is something that makes it possible to create pretty advanced libraries, e.g. a State manager that works by utilizing this to be of the data that is passed in:

type StateDescription<D, M> = {
data: D;
methods: M & ThisType<D & M>;
};

function createState<D, M>(desc: StateDescription<D, M>): D & M {
return { ...desc.data, ...desc.methods };
}

let state = createState({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx;
this.y += dy;
},
},
});

state.x = 10;
state.y = 20;
state.moveBy(5, 5);
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

As far as built-in utility types and types strip go, this type is not actually one that is often used by developers, but it is critical in how a number of popular open source libraries work, including those in the React and the view ecosystem. So let's take a look. We create these utility math functions, which are designed to be used attached to other objects. First, we define the type of this utility and then we create this utility as a simple object containing the two members, which is double and half. And of course, because we intend them to be attached to an object in order to function, we have to annotate

00:33

what this is going to be. And here we are annotating that this is something that is going to have a member value of type number. So of course we can attach it to an object that has a value of type number, for example, a value of one, and of course objective double is going to work fine. It is going to double the object of value. And similarly object do half is going to work as well. It is going to half that two back down to a one. Now, in both of these functions, we have to actually annotate what we expect this to be. Now within an object if you don't want to have to annotate this again

01:05

and again, there is a special utility type built into TypeScript called this type, which can be used to get rid of this duplicate annotation. Here we are saying that the math object is something that is going to have everything that is specified by the math type. And additionally, all usages of this within this object is going to point to something that has value of type number. And we can verify that by hovering over any of the instances of this. And you can see that it is indeed value of type number. Any usages of this beyond value of type number are going to result in a compiled time error.

01:39

Now, this type utility is actually different from some of the other utilities that are built into TypeScript in that it is actually intrinsic. It does not have a definition body. If you navigate to the definition, you can see that it is actually empty. And this is something that is actually baked into the brain of the TypeScript compiler, that this particular type means something special. This particular type is something that is used to define the definition of this within a particular object. Now, not having to annotate this again and again is definitely a good use case for the utility. However, it shines even more for describing a number

02:12

of popular libraries that exist within the JavaScript ecosystem. For example, a number of react state managers, as well as it is actually a core part of VJS. So let's demonstrate that by building a simple function that follows a similar API. For us, the definition of a state will consist of a data object along with some methods. And ha, we are annotating using the this type utility that the usage of this within the methods is going to have everything that exists within data as well as access to any of the other methods that might exist. Next, you provide a utility, create state function,

02:44

which takes a particular state description and then basically squashes the data as well as the method members into a single object, and therefore it has a return type penetration of D intersection with M. Now that's actually it for the definition of our library. Let's demonstrate How you would use it. For example, if you wanted to create a particular state with data containing X and Y of type number, and with a method move by that takes a DX and DY and modifies X and Y members, we can do that by calling create state and on the state object that is returned. We have access to X as well as Y, as well

03:16

as the move by method. Now, let's break down what is really happening over here a bit more. We are squashing data and methods into a single object, which means that this within the methods is now going to point to something that has access to both the data members as well as the methods members. And the annotation that we have of this type pointing to D as well as M is something that is enforcing that, which is why when we hover over this within the move by function, you can see that it has access to data as well as any methods. Any misusage over here is going to be caught

03:48

by TypeScript at compiled time. So thanks to the this type annotation, we get very easy access to data and we don't need to keep on going this data X and this Y. The impact of the squashing as a return type of create state is actually quite easy to define, but the impact of the squashing on the meaning of this within the methods is something that becomes very easy, only thanks to this type utility.

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