Busy TypeScript Developer’s Guide to Advanced TypeScript | Ted Neward

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] all right so first thing that we need to talk about type script one of the wonderful things about typescript by the way is the fact that it looks and feels so very much like some of the other statically typed languages that we work with in the you know in the realm of programming languages if you're a job developer if you're a c-sharp developer if you've played around with a number of the functional languages the syntax of typescript looks very very comfortable right I mean when we start talking about types and we start talking about compiling we create classes and classes can have inheritance yada yada yada right except typescript one of its fundamental notions is that typescript does not operate by what c-sharp and Java do which is called nominative typing that is to say that you are a sub type if you say you are a sub type time script instead operates off of what's called structural subtyping so here we just have three object literals x y&z X has a field write name y I'm sorry X is of a type that is a that has a single field name string Y is of a type that has a name and an age of string a number and Zed is an any which means of course I can point to anything consisting of an object literal it has name last name and age and then acts as an object literal and Wives an object literal and the only one of these that is an error is the last line okay the reason for this is that the typescript compiler looks specifically at the members of the thing that we are working with not the name see in c-sharp in Java if I have public class person string first name string last name int age and then I have public class City right name State population string string ends both of these types are a string string ends so typescript will say yeah they're equivalent because structurally they line up the same way but in c-sharp and Java we don't care about your structure c-sharp and Java are more American they only care about the name of the thing right this is why for example we banned French fries for a while calling them freedom fries instead because the name matters but only to Americans okay so this is actually going to be the basis for a lot of really interesting things that we can do in typescript that we really cannot do in a number of the other languages like C sharp Java C++ etc this is breaking new ground for a lot of developers okay now in some cases what we can do is we can actually say hey I want to I want to work with a variation of types is sometimes known as a union type so notice here at the end of this get name or number method it returns a string vertical pipe number this is basically staying a string or a number okay and when we get this thing back typescript understands that this Norn + r/n is either a string or a number but as you may well imagine there's not a lot of methods that are common to both strings and numbers so when we want to work with it we most likely have to figure out what the actual type is now remember this is not an instance of test because there's no inheritance relationship between string and number I mean yeah I suppose you could go all the way back to any but that's kind of missing the point so we can use a type assertion which is that bracketed generics looking thing on the second the last line to say I want to use this as a string okay kind of like a cast begin it's all going to be strictly type check then if you try to cast it to something else that's not a stray or a number type script will get upset with you now occasionally what we want to do is we want to actually specify certain things about these types so here for example is string it is either a string or a number and when it returns we're going to say that it will be a string this is is not particularly common right now idiomatically in typescript but we do see it show up in a couple of libraries again this is basically a type guard to say this is this is in fact the string that I'm getting back here we actually see it being done inside the body of this pad left function padding of course if you remember traditional JavaScript padding can either be a string or the number of characters to pad and so here we do as we look at the type of and if it turns out to be a number great we can use it as such notice the lack of the cast syntax that I just showed you that's because the typescript compiler is ridiculously brilliant because in this particular case it looks at that implementation it looks at the first if test and says you know what if it passes this test then it must be a number so from this point forward through the body of this if clause we can treat it as a number if that if Clause does not hold then it must be a string and therefore we can simply treat it as a string going forward so in many respects the typescript compiler is actually smarter than the c-sharp compiler which catches the number of people off-guard now we know about arrays just a quick refresher right this is an array of stuff right using either syntax the traditional JavaScript square bracket syntax or the generic style array of number all right everybody's comfortable with that yeah okay cool the Union type is something we've already talked about so here again a can be either a string or a number notice I can assign it a string I can sign it a number cannot assign it a boolean or an object or no or undefined or Never or anything else it could be either a string or a number that's the reason for the vertical pipe okay an intersection type on the other hand it's similar but this is the scenario where I say this actually is both an A and a B we're actually saying it's an and so in this scenario I have two types F 1 which is a function type taking two strings as parameters in yielding void and F 2 which is a function taking two numbers and yielding void and I now want to declare a local called f that is a u that is basically the intersection of both F 1 and F 2 what that means is that we can use this so long as it satisfies the syntax right so here F 1 and F 2 means that effectively it's going to be a function that can take a string or a number and a string or a number but here's the thing about it because this is an intersection type it has to fully satisfy the one or the other you can't mix and match so when I attempt to call F two passing two strings that satisfies it when I attempt to call F calling two numbers that satisfies it because remember it's either an F 1 or it's an F 2 but the last line will error out because it has to match the F 1 signature or the F 2 signature the reason this is an intersection type is because effectively we can use the members that are present on both types which in this case is the apply or the call method which in this case works so long as the parameter signatures are satisfied meaning two strings or two numbers it's really easy to get intersection types and union types mixed up because one is an either-or the other is an and and it kind of feels like they miss named him it feels to me like this syntax should be the Union and the other one should be the intersection but you can look it's kind of like looking at what you know which side you consider heads on a coin if that's not predetermined you can go either way this is the direction they chose to go with that particular syntax guys still with me yeah all right cool we know about tuples right tuples are basically types that are you can think of them as a fixed size array of flexible types realistically a tuple is kind of the first step towards an object it's a way to bundle up a series of fields into a single entity usually those do not have names although depending upon the language there are actually some languages that are now starting to let you name the fields of the individual fields of a tuple Ekman script 2015 which introduced the tuple type by the way they chose to use the array style syntax in order to try to minimize the cognitive load on your average JavaScript developer so here when I create a tuple of string and number type we use the square brackets and then we use the square brackets to define the instantiation thereof notice that they have to be in that particular order and if we want to extract individual values out of it we use the array subscripts and tax because again they kind of wanted tuples to feel like arrays to your average javascript F now one of the things we can do is we can D structure these tuples so here on that first line that is not a typo that empty comma that empty space right in front of the second comma is supposed to be there what we're doing is what's known as D structuring not destructing but D structuring we're slicing it up into pieces so in this particular case list one from the previous slide right if it's a if it's a three-part tuple then when I do this declar have let first comma comma third the first part of the tupple will go into the local variable first the second part of the tupple will get dropped on the floor the third part of the tupple will go into the local variable third okay notice the bracketed syntax around the let's tile so here we're effectively you can imagine again this structural theme we're taking the tupple and we're laying it down on top of these local variable declarations okay now we can also get into the rest and spread parameters right so here we see head and tail so when we D structure numbers head we'll get one which is the head of that array that list and tail we'll get everything else two three four five the reason the tuples syntax is important is as we start getting into some more advanced types gymnastics the tuples syntax will show up as a way to express type tuples so this should feel pretty comfortable if you're going to start diving into some of the more advanced stuff now one of the nice things and one of the simpler things that we'll introduced I think in 2.2 or 2.3 is this notion of enumerated types right there no enums where in 1.8 I'm thinking of something else which we'll get to in a second straight-up enum right we've got basically a bound set of cardinal operations we also have the only three good beverages in the world anybody disagree right I get in fundamentally this is gonna be backed by an integer right for a lack of anything better we'll get to the other thing that I was talking about a little bit I was getting ahead of myself how many of you have done any angular development yeah then you're already familiar with the use of decorators right we use them all the time basically to say hey I want to you know drop some additional information on this particular declaration decorators are technically not an official part of the ACMA script standard yet and as a matter of fact if we go to the typescript if we go to the typescript specification Lou come on so this is off of the typescript github and if we go look at let's see I think it was section there we go 8.6 decorators what we see them say is thank you Microsoft actually this raises an important point I want you to look very carefully at something whoops come on let me there we go what version number does that say right there and then we go back to the typescript site and what version number does that say right there here let me make sure you guys can see that very carefully now are these the same number this is one of the big detractions right now - typescript the the typescript team is a bunch of wonderful developers they have tremendous skill in language development unfortunately they lack skill and documentation the current thinking there's actually an open github issue around the fact that the specification has not been updated in I think it's two years now right and their current comment is welp the handbook right here this collection of things this is supposed to be where you go to find out everything about typescript and folks a lot of the stuff that we're going to be talking about is not listed in this handbook they actually show up in all of these what's new for each of the various versions since 1.8 so if you really want to understand typescript not only do you need to read spec you have to read the handbook and every single one of these new release documents which as everybody knows are always extremely thorough ok that was a joke y'all can laugh at that ok yeah when's the last time you wrote extensive release notes decorator's is one of those things that is actually not really described very well in the in the typescript specification the handbook has a bunch of information on it but fundamentally what we're doing here is we are providing the opportunity to invoke a function as a part of the compile time slash runtime decorators are kind of at the intersection of where compile time turns into run time so here we have an example decorators you can tell it's just a straight-up function right the only thing that makes this function a decorator is because we use it with the @ symbol on top of a declaration a class or some elements within the class a method the class itself a property property access ur which we'll get into the differences of those in just a second so in this particular case when we define the class example one is when the decorator will fire not when we use it on a one it's when we actually define the class and the decorator will actually receive a reference to the target that is to say it will receive a reference to class example one in order to be able to do something there's a lot of things angular of course will use this for a variety of purposes a lot of it will be wiring up for example between what you're writing in your typescript code and actual stuff that's in the Dom in order to be able to communicate between the two for example to know what your input and output parameters are to your particular component in order to be able to know that this is in fact a component in order to be able to know that this is supposed to be dependency injected it's a etc very powerful features in many respects decorators actually become very very close to being a full-fledged set of aspect-oriented programming anybody remember a Opie from like two decades ago this is very very close and JavaScript has always had this ability to reach in and muck with our notion of a class at runtime fundamentally this is referred to as meta object programming meta object protocols as actually the formal name for it or mo P and ironically when Gregor Cazalas sat down to create the language that would later be known as aspect J which is probably the best example of aspect-oriented programming he specifically wanted to create a constrained subset of meta object protocol so we are flirting with some you know fairly two decades old ideas and particularly if you want to see some of the the ideas people had around aspects and how did you know what you might want to consider using for decorators I would suggest you go back and look at some of the early AOP documentation specifically around the language aspect J what spring does at runtime with aspects is not really the same thing that's more of a method call interception thing which has been around even longer you can still do that here matter of fact we'll show an example of that in a bit but that's kind of the space where your head wants to be when you start thinking about decorators so what we just looked at was a class decorator it's applied to the constructor of the class right so here when we define this class this is basically the ACMA slash typescript way of creating a constructor function etc etc right and we can use it to observe modifier replace a class definition notice that last word replace this is where we start getting into some of the MLP bits so if for example you want to actually hand you want to keep your class definition tucked away somewhere and hand back proxies instead of the actual class objects class decorator would be a good way to be able to do some of that kinds of stuff etc etc etc so here's another example this is a decorator called sealed because we'd like this class to be final or as the the java spec refers to it sometimes as effectively final in other words I can't make any more changes to this particular type so the sealed function says great you're giving me a parameter which is the constructor of the class and as soon as I get that I'm gonna call object dot seal to freeze it so that this cannot be modified anymore from this point forward this is essentially how we could create final classes in a language that has never had the concept of final init ever okay we can do the same thing two methods we can actually observe modify or replace a method definition the method decorator will actually get three arguments it will get the it will get the target the property key which is basically the name of the method and then a property descriptor will see this for the next two decorator types as well a property descriptor is a formal type described in the ACMA script specification that's basically reflection information it's metadata about the thing what is its name whereas its declared what is the the the type information that set its etc so the property descriptor will give us information about it in particular there are three properties on a property descriptor about the property whether or not it is enumerable in other words will it show up in a iteration list of four of whether or not it is writable in other words can I actually modify the property on you know in terms of changing its value and I forget the third one it'll come to me later so in this particular case what I'm specifically saying is I am setting enumerable to whatever value is passed into enumerable now notice that this function in this particular case rather than doing the work itself it's returning a function this is sometimes referred to as a decorator factory because that returned function is what will be evaluated against the greet method here so in this way we pass in the value false so now when the decorator fires later we will set the greet method we will set its property descriptor to be enumerable false meaning when we enumerate across a greeter instance we will not see the greet method listed it'll still be there we can so call it you just can't enumerate it okay now access to decorators one of the things that we frequently like to do in the whole aspect oriented world was trace that was actually the first aspect that everybody ever wrote was a tracing aspect so that you could see when we entered a method and when we left the method here I'm doing it for property accessors now there's actually a difference between an accessor and the actual property the accessor is the getter our setter that go along with the field okay so those are known as accessor properties and in this particular case I'm creating a trace decorator factory that takes those again those same three parameters the targets the property key in the descriptor and in this particular case I'm looking to see if there is a getter for this particular descriptor remember we could have set only accessors right set only properties we don't do that very often but it could happen and then I'm actually going to replace the getter with my own function which in this case is going to print the property key and then whatever message I pass in and then go ahead and call the original getter this is AOP at its finest and sure enough when I run this every time I access point X or point Y it will print out basically X : in this case I just opted for the very cheap the message is really not all that important I just wanted to demonstrate how we would use it every time we call that get X that decorator will be fired so we've effectively done what the AOP guys referred to as rappers right now we can also do property decorators which are right before a property decoration but these are actually pretty limited in the sense that we can just observe that a property has been declared for a class this is partly due to some limitations and typescript and partly due to some stuff inside of the ACMA script spec from what I can understand that hasn't been formalized yet so again I'm using this trace thing but here what we're going to see is even though we have the access to get to point out X point out Y twice and then we change it those access methods will only show up once when the definition of point goes through so a property decorator will only get fired once when we define the property on the class point and access decorator will fire every time we actually access the property does that make sense yeah okay we can also do decorators around parameters I have yet to come up with a good reason to do this but it can't be done I mean angular does it specifically for dependency injection and some other kinds of things and in case it ever becomes important there is a very specific order of evaluation that typescript defines for the order in which these decorators will fire for a given class I repeat it here just because occasionally you'll be like you know if you get really really excited about using decorators you'll start using them everywhere and all of a sudden you'll get yourself into a situation where the order matters so parameter followed by method access or a property applied for each instance parameter followed by method access or a property for each static parameter for the constructor and then class decorators come last okay this would probably only be important if you were in fact trying to jig with the actual definition of the class so if a method decorator wanted to introduce some elements that the class decorator was expecting to be there the method decorator would have to put them first the class decorator couldn't put something there that the method decorator was expecting to work off of because of this order of operations I already mentioned decorator factories and forgot to put an example there but we've already seen it so the other thing we can do is we can actually compose decorators composition in the sense of functional programming so we can actually chain them so in this particular case I have two decorators F and G again the console logs are just to tell us when exactly they fire notice down here I put both decorators on this method what'll actually happen is that one will get invoked chaining to the second which will then chain to the method okay so this is your classic functional F of G composition scenario okay now generally speaking you can treat them all as independent and more often than not decorators should be written so that the order of evaluation of decorators on the class or the method should not matter just work with what you've got and don't make any assumptions about anything that's going on around you but again sometimes decorators want to be able to work together to create some higher-order functionality so know that they will compose and that you can you know if you if you insist that the F decorator must be applied before G then F could set something up that G could then pick up or something similar okay again order of evaluations generally doesn't matter all the way up until it matters okay guys still with me good because we got like another 80 slides to go there's so much stuff in here I do not expect I'm going to be able to get through all of this but I put all of it into the slide deck so that you guys will be able to look at it later but there's just Wow typescript has so many interesting things that are just not present in any other language that I've seen in the traditional static object-oriented space how many of you familiar with symbols a couple of hands one hand raised tentatively like I think baby sort of don't quiz me come on up you can do this part of the lecture no this hand is like okay now I'm gonna bury it it's way down here bad hand symbols are basically an opportunity to create unique names because one of the things that we run into with writing libraries particularly if this is all be evaluated at runtime if this is all essentially convention based then if I create a class and I have a convention that says it will be a factory if it has a create method on it cool that's awesome as long as every other library that I work with understands that convention and stays away from calling any methods create because if I'm just depending upon that string anybody could use that string and we end up with a potential meaning conflict particularly because one of the things we like to do JavaScript which we can do in typescript as well is take two objects and smash them together so that now we have one object that has all of the methods and properties of both objects because we just slam them together and there if I have a create here and a create here which one wins are kind of depends on which one was the source and which one was the destination and that's assuming we didn't create a third object to copy them both over and then yeah at this point we're with anybody's guess so specifically for ECMO script they wanted to be able to have a series of names that were going to be guaranteed to be unique that everybody could access now we sometimes will want to create a name that we know is unique and that nobody else can guess just don't get me wrong strings are helpful I don't want to type in a UUID for a method name because that's gonna suck but I want the runtime to kind of do that for me so that when I pass in a name of something I'll get a UUID that none of us will ever see but it'll be hidden behind this symbol instance and then we can use that for uniqueness so we create a symbol by giving it a string name and then we can use that symbol as the actual name for properties methods etc so because this is useful in a number of scenarios such as iterators which we'll look at in a second there is actually a property on the symbol type called iterator that contains the unique instance representing the iterator name so that now if you wish to create an iterator iterators if we want to create an iterable object all we have to do is have a method of name symbol dot iterator bracket it here what we're doing is we are actually taking the value of symbol dot iterator and using that as the name of the key for that particular method property that makes sense yeah cool now notice the iterator basically consists of a mostly optional interface the only method you really need is the next method which will return and iterate a result which is basically a named couple of a value and done value being the value that we are iterating over and done meaning are we done yet right pretty straightforward so here for example it's it's an entirely a gratuitous example of an iterator because everything I'm doing here is the same thing that's done with just a straight array so here I have a person that just has a name that's not exciting but then we have people which implements the iterable of person now an iterable knows how to create an iterate tour okay if you've done some java or some c-sharp you're already familiar with this particular concept so we just have to in order to satisfy a tour a bull and by the way we don't actually need that interface definition there right I don't actually need the implements iterable because again structural typing as long as I have the method bracket symbol iterator bracket parens parens as long as I've got that method this can be used anywhere an iterable is expected right that's just mostly so the compiler can help me make sure I got it all correct and I didn't do something stupid so here an iterator will return an iterator of type person which in this case I just create a very very simple array in Dexter and walk through it okay by the way all of the lines of code inside of the symbol iterator implementation there could have just been replaced with just asking the array for its iterator and handing it back but that's not as much fun the other thing though that it does is it sets us up to talk about generators oh and this is just using it here so we're just going to do a straight for of we were supposed to do oh there it is at the bottom for let PF pop there we go so generators are effectively a way of creating iterables that aren't necessarily tied to a collection of things okay so the whole purpose of a generator function is to create an iterable that knows how to create an iterate or that knows how to give particular values back okay now if you've spent any time in c-sharp and you've run across the yield return keyword and you had no idea what that does it was a generator it was specifically created to do this java recently introduced streams very similar concept haskell will actually call them streams and one of the interesting properties of streams is that they can be infinite I may ask you a question how many random numbers are there in the world there ever a shortage of right so if I wanted to get a collection of random numbers wouldn't it make sense that we could create a thing that would give us a steady diet of random numbers every time we wanted to ask for one this is the kind of concept you want to think about when we talk about a stream particularly an infinite stream what I really want is I want a thing that knows how to produce the next value on demand if you think about it that's what an iterator does you say give me an iterator for this array the iterator says I'm here boss and you say iterator give me the first value you have for me and he goes here you go boss then you say give me the second value says here we go boss and each time you look at that value to determine whether or not he's got more because remember part of that iterator result is the done flag right that's part of the result that gets handed back indicating whether there's more values so that way we don't ask the iterator to do something it doesn't know how to do like give me the next value off the end of the array that's generally bad right but now what we want is we want an iterator that knows how to produce that value without having to have all of those values realized ahead of time perfect example reading a file particularly if it's a large text file I could create a generator an iterator that went past a file name you say give me the next line of the file and it will read that line and hand it back I'm not loading the entire file into memory and then giving it back one line at a time if you think about it that's horribly wasteful of memory I'm saying give me the next line every time I ask for it or in this particular case when I create a function star this is kind of the weirdest syntax I've seen yet oops here I have a generator that will yield up four strings the names of being my family and then when it's done kaput now in of this you would say well okay dude four strings is not that big why not just put this into an array because for starters I may not know all of these values at compile time as a matter of fact if you can wrap your head around the idea that a generator is a function that produces an iterator that produces a value on demand you are about two steps away from understanding the whole reactive space the whole reactive observables everything it builds on this as a starting point the generator is literally the producer side of an iterable and so for example where people are getting really excited by this particularly in the user interface space Elm is when you start thinking about all of the user input as an infinite stream of mouse clicks and key actions users will never stop doing stuff so it will always be an infinite stream so now given that as an assumption how do we wire up our user interface and so forth makes sense okay and I pretty much said all of that okay here is actually a generator that you never want to use in a for loop because as you can tell it will never terminate usually when we use streams like this these infinite streams we have methods that know how to consume a fixed number of let me get the the top of let me skip the next two let me grab the first five let me take a slice of etc etc and Ekman script slash typescript are slowly getting a lot of those functions it's fairly easy to write them yourself if you wanted to but again this concept is extremely functional from the standpoint that if you can grok this then one part of Haskell that has always mystified people has suddenly landed in place for you a lot of the guys who are working on the typescript compiler have you know masters and PhDs in computer science and spent a lot of time in the functional language space one of the original PM's for the typescript compiler Luke Hoban I actually worked on the F sharp language for a number of years as a PM and spent a lot of time studying Scala and some other functional languages a lot of that crowd Eric Meyer and Simon Paton Jones they've weighed in with thoughts here so if all of this is making sense and you've never looked at a functional language before you might want to okay all right generics everybody know what generics are generics are those things that like hurt people right because generics are specifically a way to allow for type variability one of the hardest problems with understanding type systems and type variability and so forth is that it's extremely hard to debug a type system right if I write code and then execute it I can step through it and see what's happening in a step-by-step fashion but when the compilers doing all of this at compile time it's actually kind of tricky to try to see how everything fits together that's probably one of the biggest drawbacks to extremely statically type languages because they make decisions based on how these types work together and they feel like magic you're like wait how did you get from A to G here and if somebody can actually walk you through each of the steps the compiler would take you could see it but the compilers doing it all entirely in a black box generics are basically the step into that world where we are thinking about types at compile time as opposed to thinking about objects at runtime fundamentally all we're trying to do is allow for a type variable as opposed to a runtime variable you all sometimes hear the phrase arity indicating the number of parameters so a function that takes two parameters is a two arity function whereas when we create the array type in X and in typescript when we say array of T we are saying that is a one era T generic or one era T parameterised type well apparently I forgot to cut and paste the other night so hang on let's look at some generics so one of the easiest generic functions is an identity function you'll see this a lot when you when you spend time in the functional space where here this is just a function that takes a number and returns a number all right I mean it seems like a really dumb function but it lets us again we don't care about the runtime usage we care about what this is doing in terms of the type system and if you think about it there's lots of things lots of different kinds of things we'd like to get identity for right because if I try to pass a string that will not work if I try to pass a boolean that will not work if I try to pass a person that will not work we could go ahead and write the identity function to take in any right this is what the Visual Basic programmer would do just yeah just give me an anything I don't care right and so here we can get the identity of five which returns five here we get the identity of a string and those of course are exactly the same thing right well to your average VB devotee if I were in a dotnet conference I would be making fun of JavaScript developers but this is a JavaScript talk so I got to find somebody else to make fun of and VB seems really easy right this is clearly a violation of type safety right I do not want to be able to mix and match these two that's bad so what generics allow us to do as generics allow us to supply a type parameter at the time we define and use this function the brackets are necessary because the compiler needs to know that for the length of this declaration in other words for the scope of this function T is not an existing class right because if I take this out of here typescript now interprets T to be some really badly named class that somebody wrote somewhere in in in the space that we're compiling against right so the brackets are used to indicate this is the list of type parameters so that now when I use it I can supply the type explicitly by again using the brackets this is going to specifically be a numeric identity this is specifically going to be a string identity or as many of you are already aware typescript will do a certain amount of type inference it will look at this parameter say this is a string look at this function and say AHA T must be a string so therefore this T must also be a string therefore this must also be a string okay guys still with me excellent I will try to fix that I don't know when but I'll try to fix that so the types the type parameters are actually part of the signature okay so the identity function is a one arity generic function okay and that's necessary because the compiler needs to know that this type parameter will be supplied if it is not given a type parameter or if it can't figure out the type parameter then it needs to indicate an error condition to the developer and say you need to give me one or you need to reduce the ambiguity somehow okay now ah what the hell I'm caught something alright one of the things that typescript chooses to do and I'm not entirely sure I'm a fan of this is typescript actually likes using the old C++ naming conventions for parameters and parameterize types so we have T and then the next one is U and the next one is V and if we get to four type parameters god help us all that's W right tu V we just keep going down the alphabet I'm not a huge fan of this and I'm not I understand why we like the single capitalized letter because it looks out of place compared to other things but quite frankly in many cases generics can read more easily if we're actually a little bit more descriptive with our type names I mean the Java guys do it the C sharp guys do it the typescript guys are doing it but do we have to seriously right I mean frequently we will see generics that the typescript team will write that will say it takes the parameter of type T and returns a parameter of type u because T is for input and U is for return I don't know why not just call it in and out because their type parameters the typescript compiler will satisfy you know it'll put whatever in for in whatever in for out but that's not the convention okay if you write your own generics do feel free to change the convention just make sure you document it so that other people know what you're doing cuz if they've experienced typescript at other places they're probably doing this tuv okay the other thing I like to do when I was doing C++ is I use t1 t2 and t3 the T standing for type that's kind of how that started and then R or R T for a return type just it was my own convention and it helped me keep things clear in my own head so I guess I put the last 100 yes so this identity here my identity this is the function signature for the generic identity function from earlier so notice the angle bracket in front of the rounded bracket parameterised lists the type signature the type parameter is a part of the function signature needs to be there so that we know that t is a type variable okay and by the way the the letters don't have to match in the original identity function we had it as a t if i choose to express the signature as you argue you it the letters themselves don't match they are literally a placeholder for whatever type will be there okay again most of the time we use t but the last line though is where we are actually specifying this to be a typescript anonymous interface definition in some respects so here we're saying my third identity is of something that will have that singular method that takes an Oregon returns an arc of type T which gets us to the first definition here this generic identity function interface is exactly the same as the last line of the previous slide because again structural typing not nominative you do not have to implement this interface but this structurally is equivalent to that curly bracket as we can see with this my identity here and as a matter of fact I can actually reference the class Orab sorry the type parameter on the class to make it a class type parameter and now T will be visible throughout the entirety of the interface rather than just that individual function it is very possible and very desirable in a number of cases to have a class with a type parameter T and then have functions with their own individual type parameters as well don't call them T you think it's bad now if you start trying to get into school yeah just don't okay but in that case we would have class blah angle bracket T and then function blah angle bracket T or you or V or something else okay the angle brackets basically delineate the scope that this type parameter is in is available right how far it's in scope okay make sense and here we have a generic class in this case we have a generic number that has a zero value and then has a function called add that will basically do nothing well in this case it's just a function definition presumably it will be supplied elsewhere because in this first block we have a generic number of number in the second block we have a generic number of string now this could actually be a very useful building block for being able to do things where I can have numbers that have zero value strings that have zero values floats I could have matrices this is a generic number that knows that if you're going to have one of these you must provide me with a zero value and you must provide me with an add method so that now I could add matrices and I could add strings and I could just think of them all in terms of this generic number type okay now occasionally the compiler runs into problems where it says look you're telling me that there's going to be a type T that's going to be here and now you're trying to do something with that type that I can't guarantee you will be present right so for example in that commented out block of code what I want to do is I want to log the length of whatever you pass in now is everybody in this room willing to verify that every single object that will ever be passed into this function will always have a length property on it no neither will the compiler because we know that numbers don't have length we know that boolean x' don't have length there's a whole bunch of things that don't have length more importantly even if all of the known types did some future type might not this is a case where if we want the length of whatever this argument is we need to tell the compiler that T has to be constrained somehow the only acceptable types for T are those that obey this length wise interface which has a length property on it now again structural typing what this means is only types that have a length of type number property will be acceptable as a parameter for T which means strings and arrays modulo anything you create by yourself okay these constraints are what are really going to open up a whole variety of options in terms of where typescript will go because one of one of the other things we can do by the way is we can specify defaults so here I have this class called names it's a collection of names for whether they're nicknames or formal names etc now frequently we can reference names using just a string but occasionally we have formal names and as anybody who's ever were in a internationalized HR system for example as anybody knows there is no such thing as first name and last name there's surname and family name because of course as soon as you venture off into Asia frequently the family name comes first particularly in formal writing and in some cases we we have people who have middle names and in some cases we have people who have titles dr. right those who have a masters or a PhD are frequently fond of reminding people that their first name is in fact dr. right some great lines and dr. strange about that one too by the way if you've not seen that movie you need to so in this particular case we can say that names can be parameterize de round the type that will perhaps be a more complex representation of names such as my name class there which just to cheap out is just a collection of strings right which will infer later do something with but now here I have a simple names which is a names of a collection of strings notice the lack of the type parameterization on that first instantiation because if I don't supply a type parameter string is assumed in the second case I explicitly provide a type parameter so this will be a names of type name and that will then be populated with game objects now obviously within the names class I can only assume types that are string or some other complex type so not quite sure what I'll do with it from there but the example that the typescript manual uses is a create method that will hand you back a HTML element a la something from jQuery where if you don't specify what kind of HTML element to give back it'll assume it to be a div so you could just call create parens friends and get back a div or you could call create bracket form bracket and get back a forum or something similar now ready to really start warping your mind and with three minutes left awesome conditional types typescript will allow us to make some decisions about what the type of a type parameter should be based on information based on a condition so here for example we have a type name notice this is a type this is not a runtime switch it's a compile time switch by the way we discovered about 15 years ago that templates in C++ are turing-complete and typescript is I'm almost 99% certain that typescript templates are also turing-complete you could write your entire program entirely in terms of generics compile it and you know you don't even have to run it because the compilers already done all the work for you a lot of that thought is what went into the C++ boost library which is how C++ is able to do a number of the things that that Java and c-sharp can do but C++ can do it without a virtual machine because it can figure out a number of these things at compile time rather than at runtime so here if you give me type name T I will say if T extends the string so extends in this particular case is basically your conditional you can think of it as an equality operator here if T extends string notice the ternary syntax the question mark colon syntax if T extends string then the return that is to say the actual type of the type name in this case is the literal string if not if it extends number then it's a number if it extends boolean then it's boolean it said it's etc all the way down to we bottomed out an object here and notice t1 0 1 2 3 4 are each of those types respectively which means that if I create something that says hey I want to create an array of T zero fundamentally I will now have an array of string because the type here is basically a type alias yeah shut up I said shut up there we go phones I swear these things are like little masters driving us all we're slaves it's just a matter of time before we embed them in our bodies and then they start telling us what to do oh wait they already tell us what to do the conditional type thing was introduced in in typescript 2.8 and it opens up an entire world of possibility right because now effectively what I can do is I can say that this type will be either a Type A or a type B depending upon whether type a has a particular property we can combine this with type constraints so that we can say great either type a has to have this length property for example or the actual type is a type B which is a proxy around type a that provides the length property and does nothing and that my friends is the starting of the box creaking open because when you start getting into let me show you an example I was working through because it was absolutely blowing my mind if you ever want to support fully-formed currying being able to treat functions whereas just functions of multiple parameters to be able to treat them as functions of single parameters such that the end result looks like this this is extremely powerful in terms of function composition but to do that we have to actually walk through a variety of different steps - for example let's see here the head type we'll grab the first type out of an array of types and if there are no additional types then that will be of type never which by the way is the type did you know that type script introduced the never type in 2.3 I think 2.2 2.3 the never type basically is the type that is returned from functions that never return I don't make this up guys I really don't this very bluntly this is the opening of a Pandora's box okay there are is a tremendous once you now know about conditional types there's a tremendous amount of power and again turing completeness assert that we can wrestle with in the in the typescript space this article off of free code camped org where they talk about basically how to build currying you know to replace the untyped versions of currying that we see from the Randall library for example it's a very well written tutorial stepping you through step by step in terms of how all of these things will combine in order to allow us to curry I stopped about halfway through the article because then he starts figuring out how do we curry functions that yet that have rest and spread arguments and it was like okay at that point I'm just out because I don't need a curring library that does all of that for me right but it's an extremely good way to sort of come up to speed on some of the features that typescript has making use of these conditional typing capabilities again really we haven't touched on some of the new features that shipped in three zero three one three two three three three four and it is my hope my fervent hope that the typescript team will take a break at some point and go back and update the specification but right now just on as an exercise I actually created PDFs out of the 1.8 specification all of the handbook pages all of the what's new pages and it comes out to about 470 pages this is not a trivial language and please don't think that typescript is just JavaScript with a little typing thrown in these guys are thinking a much much longer more strategic game and there's a lot of stuff I'm sure they've got waiting in the wings for for them to roll out over the next several years we're not done here by any stretch of the imagination so any questions going once going twice going home [Applause] [Music] you
Info
Channel: JAX TV
Views: 32,178
Rating: 4.917902 out of 5
Keywords: jax, jax conference, jax konferenz, jax 2019, java conference, java konferenz, software-innovationen, developer talk, videos for developers, entwickler talk, videos für entwickler, software industrie trends, softwarearchitektur, ted neward, neward & associates, typescript tutorial, typescript new features
Id: wD5WGkOEJRs
Channel Id: undefined
Length: 64min 38sec (3878 seconds)
Published: Wed Oct 30 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.