1
00:00:02,250 --> 00:00:08,580
So to get started with our own generics here below loaded commented out code I will start with a generic

2
00:00:08,670 --> 00:00:12,630
function you can build generic classes and functions all show both.

3
00:00:12,630 --> 00:00:15,370
And here I'll start with a function.

4
00:00:15,390 --> 00:00:23,700
Now let's say we want to have a function which basically merges two objects and returns a new object.

5
00:00:23,700 --> 00:00:30,030
So here we could name it merge and we want to get object a an object B as a input.

6
00:00:30,050 --> 00:00:37,220
Now of course we could write this function in a certain way we could say this is of type object and

7
00:00:37,250 --> 00:00:40,070
this is of type object.

8
00:00:40,070 --> 00:00:46,550
And then what does function does is it returns the result of object assign where it get object a and

9
00:00:46,580 --> 00:00:48,160
object B.

10
00:00:48,160 --> 00:00:53,710
So of course since we get this object assign method already built into normal javascript we could argue

11
00:00:53,760 --> 00:00:55,680
if we really need a merge function.

12
00:00:55,790 --> 00:00:58,170
But of course you could be doing additional work here.

13
00:00:58,180 --> 00:01:03,100
You could enriched is with extra information with extra options and in the end does this just a demo

14
00:01:03,110 --> 00:01:04,790
just an example.

15
00:01:04,790 --> 00:01:12,760
So this would be valid we could call merge here and console log its result like this and then pass in

16
00:01:12,820 --> 00:01:17,630
an object which has a name key and a second object which has a h.

17
00:01:17,740 --> 00:01:23,770
And if we run that and we save this here in the browser indeed we get this outputs we get this merged

18
00:01:23,800 --> 00:01:24,300
object.

19
00:01:24,310 --> 00:01:39,550
Now this works the problem we have with that is if we try to store this merge name Max and age 30.

20
00:01:39,660 --> 00:01:41,340
If we tried to store this year

21
00:01:44,230 --> 00:01:46,540
I can't ex's name on the result.

22
00:01:46,570 --> 00:01:52,750
I can't access age on the results on this merged object even though we know that both will exist because

23
00:01:52,750 --> 00:01:58,840
typescript doesn't know this types we can't know this because we are just telling it you getting an

24
00:01:58,840 --> 00:02:05,110
object that Indiana type infers that we return an object which is correct but which doesn't carry all

25
00:02:05,110 --> 00:02:07,810
the information we could use here.

26
00:02:07,840 --> 00:02:09,990
Now of course we can always do typecasting.

27
00:02:10,030 --> 00:02:15,370
We can tell TypeScript and what we get back is an object where we have a name key and we have a H key

28
00:02:15,970 --> 00:02:19,080
but that's really cumbersome if we have to do that.

29
00:02:19,090 --> 00:02:21,410
So here generics can help us.

30
00:02:21,490 --> 00:02:27,190
We turned it into a generic function by adding these angled brackets after the function name and then

31
00:02:27,280 --> 00:02:29,750
we define Q identifiers.

32
00:02:29,770 --> 00:02:36,960
Typically you start with T for type but you could use any identifier here doesn't have to be a single

33
00:02:37,000 --> 00:02:37,720
character.

34
00:02:37,750 --> 00:02:42,640
But the conventions use a single character and typically if you only have one generic type you named

35
00:02:42,640 --> 00:02:43,620
as T.

36
00:02:43,780 --> 00:02:48,880
And then you say well this generic type here this is now available inside of this function so we could

37
00:02:48,880 --> 00:02:55,760
say what we get here is of type T look strange will get there no worries.

38
00:02:55,760 --> 00:02:59,630
Now here we get two arguments where we don't know exactly what it will look like.

39
00:02:59,630 --> 00:03:04,820
So I will accept a second generic type here simply by adding a comma and the angle brackets and then

40
00:03:05,030 --> 00:03:11,870
we just continue in the alphabet and Deford a second generic parameter or type you might be using in

41
00:03:12,060 --> 00:03:15,620
a function typically is named you.

42
00:03:15,680 --> 00:03:21,820
So we could say this is of type you know what test is yield us.

43
00:03:22,130 --> 00:03:28,820
Well a lot actually as you see with this alone if you hover over emerge typescript infers that this

44
00:03:28,820 --> 00:03:36,980
function returns the intersection of T and you could of course also set is explicitly like this but

45
00:03:36,980 --> 00:03:42,740
we don't even need to do that because object assign returns an intersection and therefore since we returned

46
00:03:42,740 --> 00:03:48,440
a result of object assigned types could automatically understands that this function returns the intersection.

47
00:03:48,440 --> 00:03:50,340
So how is this helpful then.

48
00:03:50,360 --> 00:03:55,610
Well if we now hover over merged object we see that now with this alone typescript understands that

49
00:03:55,610 --> 00:04:01,700
what we store in merged object is the intersection of these two object types because it sees that we're

50
00:04:01,700 --> 00:04:05,210
passing in these objects which are of these object types.

51
00:04:05,210 --> 00:04:11,630
It infers name string and h no and that our function returns the intersection.

52
00:04:11,630 --> 00:04:18,710
Why is it able to inferred is now and not with object which we had before because object is a highly

53
00:04:18,710 --> 00:04:25,310
unspecific type we say any object and yes therefore typescript is able to infer that we return the intersection

54
00:04:25,310 --> 00:04:31,970
of object and object but the intersection of two unknown objects is just a new unknown object which

55
00:04:31,970 --> 00:04:36,620
doesn't offer any additional type information to typescript with generic types.

56
00:04:36,620 --> 00:04:45,380
What we're telling typescript is that these two parameters can and often will be of different types

57
00:04:45,950 --> 00:04:51,590
and Danforth type good is able to understand dead we're not just working with some random objects type

58
00:04:51,860 --> 00:04:58,610
but dead we will get different type data here and the dysfunction overall will return the intersection

59
00:04:58,610 --> 00:05:04,070
of debt data and Danforth type good is able to understand that what we store in here in merged object

60
00:05:04,460 --> 00:05:11,360
is such intersect that data of these two inputs because now we're not just dealing with some unknown

61
00:05:11,450 --> 00:05:19,920
objects here but with very specific types and therefore for now if a console log merged object age here

62
00:05:19,950 --> 00:05:27,540
this works without errors as you can tell here I'm printing thirty because of generic types we're giving

63
00:05:27,530 --> 00:05:33,330
time of the extra information that we don't know what exactly the types will be short they will be objects

64
00:05:33,330 --> 00:05:38,460
here we can tell that but we don't know if it's an object with a name key with the H key with a Hobbes

65
00:05:38,460 --> 00:05:44,100
key we don't know and we don't care we don't care about the exact object here we don't want to specify

66
00:05:44,100 --> 00:05:49,620
that this has to be of this type because then all of a sudden if I had Hobbes in there we would have

67
00:05:49,620 --> 00:05:50,580
a problem.

68
00:05:50,580 --> 00:05:55,650
So I don't want to be that restrictive I just want to say this is of any type which I don't care about

69
00:05:55,920 --> 00:05:58,650
but it's most likely a different type than this one here.

70
00:05:58,650 --> 00:06:04,440
And if it would be the same that would be fine too but typescript understands that we do have specific

71
00:06:04,440 --> 00:06:09,840
types here for these two parameters and then we returned intersection of them instead of just having

72
00:06:09,960 --> 00:06:12,610
any unspecific object here.

73
00:06:12,720 --> 00:06:17,700
Now specifically the magic here is not just that we tell typescript that we got two different types

74
00:06:17,700 --> 00:06:24,000
here but dead these types are not set in stone when we define this function but they are set dynamically

75
00:06:24,000 --> 00:06:25,860
when we called the function.

76
00:06:25,860 --> 00:06:32,220
So here we're calling the function and types in first the types for two arguments for t it basically

77
00:06:32,220 --> 00:06:38,070
fills in an object type with an object with a name property which holds a string and a Hobbes property

78
00:06:38,070 --> 00:06:44,940
which holds an array of strings and for a you add fields in a type of type object with H property where

79
00:06:45,000 --> 00:06:48,010
h is of type No.

80
00:06:48,030 --> 00:06:54,530
Now when we call this function again in number line and we pass in different objects in a store does

81
00:06:54,550 --> 00:07:01,650
in a new constant with a new name then of course different types are filled in for t and you for this

82
00:07:01,650 --> 00:07:02,940
function call.

83
00:07:03,180 --> 00:07:09,120
You can also specifically tell types which types it should fill in by adding angle brackets after the

84
00:07:09,120 --> 00:07:15,870
function name when you call it and then you would fill in your own types for t and you we could tell

85
00:07:15,870 --> 00:07:21,070
typescript a t should be of type String for this function call and you should be of type No.

86
00:07:21,420 --> 00:07:26,340
But then of course typescript would complain about the concrete values were passing in here because

87
00:07:26,370 --> 00:07:28,070
this clearly is not a string.

88
00:07:28,190 --> 00:07:31,360
And if we would fix this this clearly would not be of type.

89
00:07:31,360 --> 00:07:32,330
No.

90
00:07:32,340 --> 00:07:38,790
So here we could be very specific and say well the first argument were the type t to be precise for

91
00:07:38,790 --> 00:07:45,210
this function call here will be an object type where we have a name property which is of type String

92
00:07:45,510 --> 00:07:52,320
and a Hobbes property which is of type String array and the concrete type for you for this function

93
00:07:52,320 --> 00:07:57,330
call will be an object where we have a property which should be of type no.

94
00:07:57,390 --> 00:08:02,560
And now we would be good and no errors would be there anymore and this would work.

95
00:08:02,790 --> 00:08:04,090
But this is redundant.

96
00:08:04,140 --> 00:08:09,120
You can absolutely do that and it is important to understand that this is in the end what generics are

97
00:08:09,120 --> 00:08:15,750
all about that you can fill in different concrete types for different function calls but we don't need

98
00:08:15,750 --> 00:08:21,750
to do that here because typescript simply infers the types of the values we're passing as arguments

99
00:08:21,750 --> 00:08:28,230
here and then add plaques in the inferred types for t and you for this function call.

100
00:08:28,290 --> 00:08:31,170
That's how generics work behind the scenes in the end.
