Skip to content

Commit 12d3c6b

Browse files
committed
done with chapter 8
1 parent afc790d commit 12d3c6b

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,10 @@
5959
- [Section 7.5: Accessors](/book_pages/chapter7/section7.5.md)
6060
- [Section 7.6: Transpilation](/book_pages/chapter7/section7.6.md)
6161
- [Section 7.7: Monkey patch a function into an existing class](/book_pages/chapter7/section7.7.md)
62+
63+
* Chapter 8: Class Decorator
64+
65+
- [Section 8.1: Generating metadata using a class decorator](/book_pages/chapter8/section8.1.md)
66+
- [Section 8.2: Passing arguments to a class decorator](/book_pages/chapter8/section8.2.md)
67+
- [Section 8.3: Basic class decorator](/book_pages/chapter8/section8.3.md)
6268

book_pages/chapter8/section8.1.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Section 8.1: Generating metadata using a class decorator
2+
3+
This time we are going to declare a class decorator that will add some metadata to a class when we
4+
applied to it:
5+
```ts
6+
function addMetadata(target: any) {
7+
// Add some metadata
8+
target.__customMetadata = {
9+
someKey: "someValue"
10+
};
11+
// Return target
12+
return target;
13+
}
14+
15+
// We can then apply the class decorator:
16+
@addMetadata
17+
class Person {
18+
private _name: string;
19+
public constructor(name: string) {
20+
this._name = name;
21+
}
22+
public greet() {
23+
return this._name;
24+
}
25+
}
26+
27+
function getMetadataFromClass(target: any) {
28+
return target.__customMetadata;
29+
}
30+
31+
console.log(getMetadataFromClass(Person));
32+
```
33+
34+
The decorator is applied when the class is declared not when we create instances of the class. This means
35+
that the metadata is shared across all the instances of a class:
36+
```ts
37+
function getMetadataFromInstance(target: any) {
38+
return target.constructor.__customMetadata;
39+
}
40+
41+
let person1 = new Person("John");
42+
let person2 = new Person("Lisa");
43+
44+
console.log(getMetadataFromInstance(person1));
45+
console.log(getMetadataFromInstance(person2));
46+
```

book_pages/chapter8/section8.2.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Section 8.2: Passing arguments to a class decorator
2+
3+
We can wrap a class decorator with another function to allow customization:
4+
```ts
5+
function addMetadata(metadata: any) {
6+
return function log(target: any) {
7+
// Add metadata
8+
target.__customMetadata = metadata;
9+
10+
// Return target
11+
return target;
12+
}
13+
}
14+
```
15+
The addMetadata takes some arguments used as configuration and then returns an unnamed function which is
16+
the actual decorator. In the decorator we can access the arguments because there is a closure in place.
17+
We can then invoke the decorator passing some configuration values:
18+
```ts
19+
@addMetadata({ guid: "417c6ec7-ec05-4954-a3c6-73a0d7f9f5bf" })
20+
class Person {
21+
private _name: string;
22+
23+
public constructor(name: string) {
24+
this._name = name;
25+
}
26+
27+
public greet() {
28+
return this._name;
29+
}
30+
}
31+
32+
// We can use the following function to access the generated metadata:
33+
function getMetadataFromClass(target: any) {
34+
return target.__customMetadata;
35+
}
36+
37+
console.log(getMetadataFromInstance(Person));
38+
39+
// If everything went right the console should display:
40+
{ guid: "417c6ec7-ec05-4954-a3c6-73a0d7f9f5bf" }
41+
```

book_pages/chapter8/section8.3.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Section 8.3: Basic class decorator
2+
3+
A class decorator is just a function that takes the class as its only argument and returns it after doing
4+
something with it:
5+
```ts
6+
function myClassDecorator<T>(target: T) {
7+
// Do something with target
8+
console.log(target);
9+
10+
// Return target
11+
return target;
12+
}
13+
14+
// We can then apply the class decorator to a class:
15+
@myClassDecorator
16+
class Person {
17+
private _name: string;
18+
19+
public constructor(name: string) {
20+
this._name = name;
21+
}
22+
23+
public greet() {
24+
return this._name;
25+
}
26+
}
27+
```

0 commit comments

Comments
 (0)