1
00:00:02,340 --> 00:00:08,940
Now in Javascript, we can work with classes to define blueprints for objects, right?

2
00:00:09,030 --> 00:00:13,510
And of course we can use classes in Typescript as well, it supports this feature as well

3
00:00:13,560 --> 00:00:17,250
and since it compiles code to code that works in older browsers as well,

4
00:00:17,280 --> 00:00:23,880
it even compiles class code down to Javascript code that does not use classes but constructor functions

5
00:00:23,880 --> 00:00:26,640
and runs in older browsers as well.

6
00:00:26,640 --> 00:00:31,560
Now let's stick to this file and let's say in there, maybe at the very top

7
00:00:31,570 --> 00:00:33,220
but that does not matter,

8
00:00:33,220 --> 00:00:38,760
we want to define a class for a user in our app.

9
00:00:38,830 --> 00:00:40,940
Now this is how we can define a class

10
00:00:41,050 --> 00:00:45,160
and now in this class, we can add a constructor function and

11
00:00:45,160 --> 00:00:51,170
we can expect a name which is of type string and an age which is of type number let's say

12
00:00:51,390 --> 00:00:58,630
and then here we say this name equals name and this age equals age and now we would have these two properties

13
00:00:58,630 --> 00:01:04,190
here in our class and already, we get an error, property name does not exist on type user.

14
00:01:04,450 --> 00:01:12,520
Now in vanilla Javascript, this would be a valid syntax we could use, not so in Typescript, instead there

15
00:01:12,850 --> 00:01:20,200
we have to add property as fields all the time, every time we want to work with a property. In Javascript,

16
00:01:20,260 --> 00:01:26,440
the field syntax is pretty new and experimental and not supported by all browsers but since Typescript

17
00:01:26,440 --> 00:01:31,990
gets compiled down to Javascript code which will work in all browsers, Typescript can enforce certain

18
00:01:31,990 --> 00:01:35,100
features which wouldn't work in browsers otherwise

19
00:01:35,260 --> 00:01:44,200
and here we have to simply add name and age as fields up there so that we can work with them in here

20
00:01:44,200 --> 00:01:45,910
in the constructor.

21
00:01:46,020 --> 00:01:47,440
This is just how Typescript works,

22
00:01:47,440 --> 00:01:52,640
it forces us to use this setup because this in the end just leads to cleaner code,

23
00:01:52,630 --> 00:01:58,360
other developers reading our code can quickly see which fields, which properties this user class will have and

24
00:01:58,870 --> 00:02:00,790
of course for this simple class,

25
00:02:00,790 --> 00:02:03,670
it wouldn't have been too hard by just looking at the constructor

26
00:02:03,850 --> 00:02:09,640
but if this is a bigger class with a lot of properties that get added everywhere throughout the class,

27
00:02:09,940 --> 00:02:15,680
having a list of properties right at the top can be very greetable and very helpful.

28
00:02:15,760 --> 00:02:19,190
So that's how we can define such a class in Typescript.

29
00:02:19,240 --> 00:02:26,560
Now in addition, Typescript also gives us access modifiers, we can make it clear whether a property is

30
00:02:26,560 --> 00:02:32,420
intended to be used from only inside the class or also from outside of it

31
00:02:32,620 --> 00:02:38,920
and there for example, we could lock down the age to be used from only inside by adding private.

32
00:02:38,920 --> 00:02:44,230
The opposite is public but you don't need to add this because it's a default anyways, so you can add it

33
00:02:44,260 --> 00:02:45,640
but you don't have to.

34
00:02:45,820 --> 00:02:49,410
Now age is really only usable from inside this class,

35
00:02:49,420 --> 00:03:04,190
if I create a user here with new user and I feed in Max and 30, I can console log user.name but if

36
00:03:04,190 --> 00:03:07,330
I try to access .age, I get an error.

37
00:03:07,400 --> 00:03:12,290
Now technically, Javascript of course doesn't really have private properties or at least it's a very

38
00:03:12,500 --> 00:03:14,950
new feature which is not supported everywhere,

39
00:03:15,020 --> 00:03:20,550
so technically once this is compiled to Javascript, this privateness is lost,

40
00:03:20,600 --> 00:03:26,600
it's just a Typescript feature so that in your Typescript code, you can't access this and you get an error.

41
00:03:26,630 --> 00:03:30,730
So the developers writing code know okay I shouldn't access this property,

42
00:03:30,800 --> 00:03:33,070
this code is not the code I should write,

43
00:03:33,080 --> 00:03:34,480
that's the idea here,

44
00:03:34,670 --> 00:03:42,000
using the name is fine because that is public of course. And now there also is a little shortcut in Typescript,

45
00:03:42,120 --> 00:03:49,320
we can set up our class like this but I'll copy it here and comment it out because for this common scenario

46
00:03:49,320 --> 00:03:54,090
where you have a couple of fields and then you assign values to them in the constructor, you can shorten

47
00:03:54,090 --> 00:04:00,630
this and actually get rid of these fields and instead add the access modifiers here in front of the parameters

48
00:04:00,690 --> 00:04:01,770
in the constructor

49
00:04:01,830 --> 00:04:05,960
and that's simply a special feature available in the constructor of a class.

50
00:04:06,240 --> 00:04:14,100
By doing this, you tell Typescript these parameters should also be automatically converted to properties

51
00:04:14,330 --> 00:04:18,110
of this class and therefore we can also get rid of these lines.

52
00:04:18,180 --> 00:04:25,290
So this class will do exactly the same thing as this class did, simply because of this shorthand Typescript

53
00:04:25,300 --> 00:04:26,610
supports to you,

54
00:04:26,610 --> 00:04:32,190
this makes it clear that Typescript should add a name property to this class and the age property and the

55
00:04:32,190 --> 00:04:37,290
value passed in for the name parameter should be stored in the name property, the value passed in for

56
00:04:37,290 --> 00:04:42,320
the age parameter should be stored in the age property and the name property will be public,

57
00:04:42,330 --> 00:04:47,650
the age property will be private, so the same thing we have up there but a bit easier,

58
00:04:47,670 --> 00:04:50,010
that's a huge advantage.

59
00:04:50,070 --> 00:04:52,770
So this is how we can work with a class here.

60
00:04:52,770 --> 00:05:00,690
Now of course in Typescript, just as in vanilla Javascript, we can also inherit. We can add an admin class

61
00:05:00,720 --> 00:05:03,230
which extends the user class let's say

62
00:05:03,470 --> 00:05:11,080
and this now simply allows us to add additional fields, for example here in the constructor,

63
00:05:11,080 --> 00:05:18,780
we could also have a private or public, whatever you want, property named permissions

64
00:05:18,950 --> 00:05:22,240
and this let's say is an array of strings, whatever you want

65
00:05:22,370 --> 00:05:32,250
and now we just have to call super in here and therefore also accept a name here and an age, in this case

66
00:05:32,550 --> 00:05:39,060
without using the shortcut because I will forward name and age to the super constructor, so of the base

67
00:05:39,060 --> 00:05:48,280
class and also add my own property here, this private permissions property which holds an array of strings.

68
00:05:48,400 --> 00:05:53,470
So this is how we can extend a class, how we can still use this shortcut and call super which we

69
00:05:53,470 --> 00:05:59,830
do have to do if we extend a base class and bring our own constructor and now we can of course work

70
00:05:59,830 --> 00:06:06,340
with either that class or that class, just the way you are used to from vanilla Javascript classes in

71
00:06:06,340 --> 00:06:16,650
the end. Now kind of related to classes but also different is a Typescript exclusive feature called interfaces.

72
00:06:16,650 --> 00:06:20,860
Now when you define a class, you have a blueprint for an object right

73
00:06:20,970 --> 00:06:24,520
and you can always instantiate a class as we're doing it down there.

74
00:06:24,720 --> 00:06:32,070
Now sometimes you just want a blueprint but you don't want to instantiate it because it's very simple,

75
00:06:32,070 --> 00:06:38,670
it doesn't have any methods and you just don't want to call new and create a object like this but create it

76
00:06:38,670 --> 00:06:42,470
with the curly braces and still have that extra type safety.

77
00:06:42,480 --> 00:06:48,570
Now in such a scenario, you can of course use an alias, here for example I do store an object in there

78
00:06:48,990 --> 00:06:58,800
but you could also use an interface, an interface maybe named calculation container here.

79
00:06:59,790 --> 00:07:05,340
You create it with the interface keyword, then any name of your choice which should start with a capital

80
00:07:05,370 --> 00:07:05,950
character

81
00:07:05,970 --> 00:07:12,270
just as for custom types and classes and in there you could define how an object should look like,

82
00:07:12,330 --> 00:07:21,940
that you have a res property which is a number and then maybe also a print method which returns nothing,

83
00:07:21,960 --> 00:07:29,680
this is how you then define it here. You could also use this syntax if you wanted to but I will go for

84
00:07:29,680 --> 00:07:31,550
the method syntax.

85
00:07:31,600 --> 00:07:38,230
So now this is an interface and we can't use new with it, new with calculation

86
00:07:41,560 --> 00:07:46,450
container will not work but we can use it as a type,

87
00:07:46,450 --> 00:07:56,890
for example here we can use the calculation container and have an array of calculation containers and

88
00:07:56,920 --> 00:08:01,750
our other code will work because we define in there we want to have an object with this structure

89
00:08:02,140 --> 00:08:04,650
and that's exactly what we create down there.

90
00:08:05,540 --> 00:08:10,740
So you can use this as a blueprint for objects which you create with curly braces instead of with the

91
00:08:10,740 --> 00:08:12,030
new keyword

92
00:08:12,230 --> 00:08:17,540
but like this, it's simply just an alternative to the type keyword because this is basically the same

93
00:08:17,870 --> 00:08:21,560
as if we would have set type calculation container equals this,

94
00:08:21,570 --> 00:08:24,080
this is also something we could have done.

95
00:08:24,290 --> 00:08:26,420
So why do we have interfaces

96
00:08:26,420 --> 00:08:33,200
if they're just an alternative to the type keyword? Well besides using them for object type definitions,

97
00:08:33,590 --> 00:08:37,430
you can also use them as contracts in classes.

98
00:08:37,430 --> 00:08:38,450
What do I mean by that?

99
00:08:38,960 --> 00:08:47,570
Well we can define an interface, maybe name it greetable, where we say we want to have a name which is

100
00:08:47,570 --> 00:08:54,920
of type string and now in our class we can do something which is called implement the interface and

101
00:08:54,920 --> 00:08:56,570
that's a pure Typescript feature,

102
00:08:56,570 --> 00:08:59,450
this does not exist in vanilla Javascript.

103
00:08:59,450 --> 00:09:01,250
Now what does this do?

104
00:09:01,250 --> 00:09:08,120
It forces this user class to have a public name property which is of type string and if I would remove

105
00:09:08,180 --> 00:09:15,470
this here, this parameter property assignment, I correctly would get an error that the class user incorrectly

106
00:09:15,470 --> 00:09:17,680
implements the interface greetable,

107
00:09:17,750 --> 00:09:21,620
that's why I refer to interfaces also as contracts.

108
00:09:21,770 --> 00:09:28,850
Besides using them as blueprints for objects, you can also use them to force classes to have a certain

109
00:09:28,850 --> 00:09:31,670
structure, to bring certain properties,

110
00:09:31,670 --> 00:09:39,680
classes can then always add more than what the interface demands but never less. Now you might wonder why

111
00:09:39,680 --> 00:09:40,930
would you do that,

112
00:09:40,970 --> 00:09:44,000
you are the developer, you are writing the code,

113
00:09:44,060 --> 00:09:48,650
why would you force yourself to build a class in a certain way.

114
00:09:48,650 --> 00:09:51,020
If you want to do that, you can just do that.

115
00:09:51,020 --> 00:09:56,480
Well for one, keep in mind if you're working in bigger projects, it can be hard to keep track of what

116
00:09:56,480 --> 00:09:58,360
you want to do where,

117
00:09:58,490 --> 00:10:04,100
also if you're working in a team it can be helpful, to force other developers to do something in a certain

118
00:10:04,100 --> 00:10:04,630
way

119
00:10:04,640 --> 00:10:09,060
so that you all use the same style and you're working on the same goal

120
00:10:09,110 --> 00:10:14,170
and here it might get clearer if we maybe create another interface, printable,

121
00:10:14,210 --> 00:10:20,120
you don't have to name it like this but that's a convention you will often see and there you say that

122
00:10:20,120 --> 00:10:21,920
you want to have a print method,

123
00:10:21,920 --> 00:10:24,220
then you could implement this as well.

124
00:10:24,260 --> 00:10:28,260
You can implement multiple interfaces by simply separating them with a comma

125
00:10:28,460 --> 00:10:33,800
and now you would be forced to add a print method here which does something, we don't know

126
00:10:33,800 --> 00:10:36,750
what but it does something.

127
00:10:36,830 --> 00:10:42,020
Now we can make it clear that every class which has a printable interface, that implements a printable

128
00:10:42,020 --> 00:10:48,890
interface needs to have a print method and this can give us extra type safety because maybe we got another

129
00:10:48,890 --> 00:10:54,830
part in our code where we are not interested in the exact type of object we're working with, we're not

130
00:10:54,830 --> 00:10:58,820
interested in the fact whether it's a user or an admin or a horse

131
00:10:59,240 --> 00:11:04,600
but we are interested in the fact that we can call print. In such a scenario,

132
00:11:04,610 --> 00:11:12,320
we could simply assign to type printable to the parameter or variable that stores our object and it

133
00:11:12,320 --> 00:11:16,980
would be clear that whatever is stored in there will have a print method which we can call.

134
00:11:17,000 --> 00:11:25,820
So this is why we can use interfaces as contracts to give us extra type safety and guarantee that certain

135
00:11:25,820 --> 00:11:32,930
classes and therefore the new objects built on those classes have a certain structure, have certain methods

136
00:11:33,230 --> 00:11:37,460
and that is something you will also see a lot when you are working with Typescript.

137
00:11:37,550 --> 00:11:45,560
Now I do want to emphasize that if you compile this file, interfaces are totally lost. We see a lot of code

138
00:11:45,560 --> 00:11:50,840
here because it was compiled to code that doesn't use the class keyword, hence we don't see the class

139
00:11:50,840 --> 00:11:52,130
keyword here

140
00:11:52,130 --> 00:11:58,010
but we won't see the interface here, so this is a pure Typescript feature which gives us extra type

141
00:11:58,010 --> 00:12:00,260
safety whilst we're working in Typescript.
