You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/9/en/part9d.md
+14-14Lines changed: 14 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -310,7 +310,7 @@ const App = () => {
310
310
311
311
### Deeper type usage
312
312
313
-
In the previous exercise, we had three parts of a course, and all parts had the same attributes *name* and *exerciseCount*. But what if we needed additional attributes for the parts and each part needs different attributes? How would this look, codewise? Let's consider the following example:
313
+
In the previous exercise, we had three parts of a course, and all parts had the same attributes *name* and *exerciseCount*. But what if we needed additional attributes for the parts not all parts have the same attributes? How would this look, codewise? Let's consider the following example:
314
314
315
315
```js
316
316
constcourseParts= [
@@ -343,7 +343,7 @@ Each part has the *name* and *exerciseCount* attributes, but the first, the thir
343
343
344
344
Let's imagine that our application just keeps on growing, and we need to pass the different course parts around in our code. On top of that, there are also additional attributes and course parts added to the mix. How can we know that our code is capable of handling all the different types of data correctly, and we are not for example forgetting to render a new course part on some page? This is where TypeScript comes in handy!
345
345
346
-
Let's start by defining types for our different course parts. We notice that the first and third have a same set of attributes, and the second and fourth are a bit different so we have three different kinds of course part elements.
346
+
Let's start by defining types for our different course parts. We notice that the first and third have the same set of attributes. The second and fourth are a bit different so we have three different kinds of course part elements.
347
347
348
348
So let us define a type for each of the different kind of of course parts:
Besides the fields that are found in the entries, we have now introduced a additional field called <i>kind</i> that has a [literal](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) type. The field kind is describing what "kind of" course part the type represents. We shall soon see where the field kind is used!
374
+
Besides the attributes that are found in the various course parts, we have now introduced a additional attribute called <i>kind</i> that has a [literal](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) type, it is a "hard coded" string, distinct for each course part. We shall soon see where the attribute kind is used!
375
375
376
376
Next, we will create a type [union](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) of all these types. We can then use it to define a type for our array, which should accept any of these course part types:
377
377
@@ -416,7 +416,7 @@ const App = () => {
416
416
}
417
417
```
418
418
419
-
Note that we have now added the field _kind_ with a proper value to each element of the array.
419
+
Note that we have now added the attribute _kind_ with a proper value to each element of the array.
420
420
421
421
Our editor will automatically warn us if we use the wrong type for an attribute, use an extra attribute, or forget to set an expected attribute. If we eg. try to add the following to the array
422
422
@@ -433,7 +433,7 @@ We will immediately see an error in the editor:
433
433
434
434

435
435
436
-
Since our new entry has the field <i>kind</i> with value <i>basic</i> TypeScript knows that the entry is does not only have the type _CoursePart_ but it is actually meant to be a _CoursePartBasic_. So here the field _kind_ "narrows" the type of the entry from a more generic type to a more specific type that has a certain set of fields. We shall see this style of type narrowin in action in the code soon!
436
+
Since our new entry has the attribute _kind_ with value _"basic"_ TypeScript knows that the entry is does not only have the type _CoursePart_ but it is actually meant to be a _CoursePartBasic_. So here the attribute _kind_ "narrows" the type of the entry from a more general to a more specific type that has a certain set of attributes. We shall soon see this style of type narrowing in action in the code!
437
437
438
438
But we're not satisfied yet! There is still a lot of duplication in our types, and we want to avoid that. We start by identifying the attributes all course parts have in common, and defining a base type that contains them. Then we will [extend](https://www.typescriptlang.org/docs/handbook/2/objects.html#extending-types) that base type to create our kind-specific types:
How should we now use these types in our components?
468
468
469
-
If we try acess the objects in the array _courseParts: CoursePart[]_ we notice that it is possibly to only access the attributes that are common to all the union types:
469
+
If we try to acess the objects in the array _courseParts: CoursePart[]_ we notice that it is possibly to only access the attributes that are common to all the types in the union:
470
470
471
471

472
472
473
-
And indeed, the TypeScript [documentation](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#working-with-union-types) mentions:
473
+
And indeed, the TypeScript [documentation](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#working-with-union-types) says this:
474
474
475
-
> <i>TypeScript will only allow an operation if it is valid for every member of the union.</i>
475
+
> <i>TypeScript will only allow an operation (or attribute access) if it is valid for every member of the union.</i>
476
476
477
477
The documentation also mentions the following:
478
478
479
-
> <i>The solution is to narrow the union with code, the same as you would in JavaScript without type annotations. Narrowing occurs when TypeScript can deduce a more specific type for a value based on the structure of the code.</i>
479
+
> <i>The solution is to narrow the union with code... Narrowing occurs when TypeScript can deduce a more specific type for a value based on the structure of the code.</i>
480
480
481
481
So once again the [type narrowing](https://www.typescriptlang.org/docs/handbook/2/narrowing.html) is the rescue!
482
482
483
-
One handy way to narrow these kinds of types in TypeScript is by using *switch case* expressions. Once TypeScript has inferred that a variable is of type union and that each type in the union contain a certain literal attribute (in our case <i>kind</i>), we can use that as a type identifier. We can then build a switch case around that attribute and TypeScript will know which attributes are available within each case block:
483
+
One handy way to narrow these kinds of types in TypeScript is to use *switch case* expressions. Once TypeScript has inferred that a variable is of union type and that each type in the union contain a certain literal attribute (in our case _kind_), we can use that as a type identifier. We can then build a switch case around that attribute and TypeScript will know which attributes are available within each case block:
484
484
485
485

486
486
487
-
In the above example, TypeScript knows that a *part* has the type *CoursePart* and it can then infer that *part* is of either type *CoursePartBasic*, *CoursePartGroup* or *CoursePartBackround* based on the value of the atrribute _kind_.
487
+
In the above example, TypeScript knows that a *part* has the type *CoursePart* and it can then infer that *part* is of either type *CoursePartBasic*, *CoursePartGroup* or *CoursePartBackround* based on the value of the attribute _kind_.
488
488
489
-
The specific technique of type narrowing where a union type is narrowed based on one attrribute value is called [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions).
489
+
The specific technique of type narrowing where a union type is narrowed based on literal attribute value is called [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions).
490
490
491
-
Note the narrowing can naturally be also done with _if_ clause. We could eg. do the following:
491
+
Note that the narrowing can naturally be also done with _if_ clause. We could eg. do the following:
492
492
493
493
```js
494
494
courseParts.forEach(part=> {
@@ -524,7 +524,7 @@ default:
524
524
returnassertNever(part);
525
525
```
526
526
527
-
and remove the case that handles the type_ CoursePartBackround_, we would see the following error:
527
+
and remove the case that handles the type _CoursePartBackround_, we would see the following error:
0 commit comments