Utility Types - Advanced TypeScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
typescript provides a set of utility types which we can use to create a type which is based on some other type and this new type will be transformed in some way each of these utility types provides the transformation which we can apply to one of our types in this series I would like to talk about each of these types one by one let's start with partial partial is a generic type which takes one generic type parameter T which is an interface let's say we have interface a with two required properties x and y if we apply partial to this interface we get a new type with all the properties from the interface a optional let me show you an example let's create an interface called starship it has a name and one more property let's call it an able hyper jump which is a boolean notice that both properties are required now I would like to create a function that allows the developer to update some property of the starship object like only the name or only the enable hyper jump property so let's go ahead and type the function name let's call it update starship this function should take two parameters the first one is the idea of the starship let's say it's a number and the second parameter is the object with starship properties that we would like to update let's describe it as starship for now now let's try to use this function to update only in the name of a starship so let's update starship is ID 1 and update its name to explore now we have an error because starship that we described in here should have two properties two required properties but in here we provided a starship object with one property we didn't provide the second required property so in order to fix this error right now we have to provide the second property and now our starship object is complete but what if I wanted to update only the name for this I would describe the starship object in our function as partial starship meaning that the starship object is of starship type but all the properties of the starship type become optional in this case and now our function works with any properties that we would like to update we've got the required type it's again a generic type which takes one generic type parameter which should be an interface the say we have interface a these two properties which are optional when we apply the required type two interface a we get a new type with all the properties of interface a and the properties that were optional become required read-only it only takes one generic type parameter which should be an interface here again we've got interface Avis - required properties X&Y that we apply read-only to a we get a new type with all the properties of a being read-only meaning that when we create an object that is described by this return the a type we can't overwrite its properties so if the property X or Y is set we won't be able to overwrite it the record type quite frequently in programming to recreate Maps these are objects will restore values under some keys like in here for example we've got an object very store the quantity of a fruit so here we've got four keys we've got apples and oranges and for the values we've got the quantities 10 and 20 so we've got ten apples and 20 oranges and in order to describe such a map in typescript we can use the record type which is a generic type which takes two generic type parameters the first one is the type of the key which in this case is a string because apples and oranges keys are represented by a string and for the value we specify the number type because the quantities are numbers let me show you another example in here I would like to create a map of starships where I will store each starship under its name so let's create an map called starships and let's use the record type to describe it for the keys I will use strings the starship names and for the values I will use the starship object okay now let's create our first starship Explorer one and map it to the starship object that is related to Explorer one it's called Explorer one we're hyperjump is enabled let's create one more Explorer too let's disable hyperjump in here okay so this is how we can easily describe a map in typescript the peak type peak allows us to create a new type based on some other type with only the properties from the original type that we would like to have in the new type and here we have interface a with three properties XY and Z if we apply peak to our interface a and in here I would like to pick only the property X and Z we will get a new type with only the properties that we picked in here let me show you an example in here we've got the starship interface and I would like to create a new type based on this interface with only the name property so it to the following and here I type from starship interface I would like to pick only the name property and for the result I get a new type with only the name property from the starship now let's talk about the omit type it's opposite to pick we have interface a again these three properties XY and Z in this case I would like to UM meet some properties instead of picking them so in here i omit property X and Z and for the result I get a new type with all the properties that I did not omit in here and in our case it's only property of Y let me show you an example again in here I would like to create a new type based on the starship interface omitting the name of a star so here I type on meat from starship the name and for the result I get a new type with only the enable hyper jump property in this case so basically I get a new type with all the properties that I did not omit okay let's talk about the exclude type exclude type allows us to subtract one Union type you from another 1t let's say we have type A which is a union type that consists of string and there are strings or undefined and we would like to have a new type with undefined excluded so we do the following from type a we exclude the type undefined and for the result we get the part of type a that doesn't have undefined which is string or an array of strings now let me show you an example let's say we have a restaurant with two visitors john and jane and we would like to serve each of them a drink so let's create a type to describe the available drinks let's say it's coffee tea or orange juice or lemonade okay now let's serve a drink for John John doesn't have a preference so let's serve him any drink out of the available drinks behalf let's create a variable for the drink I'll call it John string and I will describe it simply as available drinks and now I can serve him let's say a coffee okay now let's serve a drink for Jane Jane has some preferences so let's create the type to describe the drinks which Jane doesn't like okay and Jane doesn't like coffee and let's say orange juice so we shouldn't serve her these drinks now let's create a variable to store the Jane's drink and now we should describe the Jane's drink has available drinks - the drinks she doesn't like so we can use exclude to exclude the drinks she doesn't like from available drinks so from available drinks we exclude the drinks that Jane doesn't like and for the resulting type we get the list of drinks Jane can drink like the tea and lemonade so the drinks that she doesn't like coffee or orange juice have been subtracted from the available drinks type and now we for example cannot serve her a coffee we will get a type script error oh I should have used the Jane's drink variable okay so we cannot serve her coffee because we get a type script error so let's serve something that she would like to drink let's say a tea okay so this is how we can use the exclude type now let's talk about extract extract is opposite to exclude let's describe the drinks the chain likes drinks Jane likes and she likes tea lemonade and let's say mojito this is the type that is not available in our drinks list okay now let's describe the Jane's drink using extract to extract out of available drinks only the drinks Jane likes so we use extract from available drinks we extract the drinks Jane likes so out of this list we extract only the tea lemonade and mojito but because mojito is not in the available drinks list it will not be extracted so for the result we get jane's drink described as tea or lemonade so this is how we can use the extract type now let's talk about the non na level type it takes one generic type parameter T which should be a union type like the type A which is a union type of string array of strings null and undefined now I would like to create a type that is exactly as type a but without null and undefined for this I apply the non nullable type to the type a and for the result I get the part of a result now and undefined let me show you an example let's say we have an interface called starship properties in here we have the colored property which is optional and can be either blue red or green next I would like to create a function that will paint some starship into one of these available colors so let's call this function paint starship let's take the starship ID and the color we would like to paint in this starship inter let's describe the color as the type of the property color so it I have starship properties and in square brackets we type the color property now because the color property in here is optional we can call the paint starship function this undefined for in the color and this would work now but I don't want to paint a starship into an undefined color so I would like to make sure that the developer who uses the paint starship function won't be able to use undefined or now for the color so I would use the non malleable type to accomplish this and now the developer is still able to assign undefined to the color what is happening here well by default typescript allows us to assign a null and undefined to any type if we create a variable let's call it a and say it should be a string we can assign null or undefined to it so to make sure that we can't assign null or undefined to a type that doesn't explicitly say that it can be undefined or now we should enable the option called Street null checks and to an in this project we can use the TS config JSON and inside we define the compiler options and enable the strict null checks option okay now the editor uses this TS config JSON to compile the typescript file here and we cannot assign null to a because a is exactly a string and doesn't allow null or undefined and also we cannot assign undefined because color is non knowable meaning that it cannot be null because we removed the possibility of now or undefined from this type from the color property type so we have to specify the color exactly blue green or red now let's talk about the return type type it takes one generic type parameter T which is a type definition of a function in here we've got the function called hello world which returns a string next we try to extract the return type of this function and here we use the typeof operator to get the type signature of this function because we cannot provide the function itself as the generic type parameter we should provide the functions type let me show you an example in here we've got the paint starship function from the previous example let's say unsuccess this function returns an object with the ID and the color properties now let's try to extract the type of the return value of this function let's name this type paint starship turn reapply the return type to the type signage er of the paint starship function and to extract the functions type we use the type of operator on the paint starship function and for the result we get the following type an object with ID and color properties let's talk about the instance type it takes one type parameter T which should be the type of the static side of a class we have a simple class car with public property name public method to drive a simple constructor and a static method called build car next we try to extract the instance type out of the class car for this we use the instance type with the statement type of car we use stamp off and not car directly to get the type of the static side of the car class we use temp off because the instance type expects the type of the static side finally as the result of this statement we get the car which doesn't make sense in this case because why not use car directly without this long line of code well in this case the instance type is useless but it can be very useful in other situations like for example with the mixing pattern let me show you an example let's create the car class and the class user it also has constructor fees the name property let's say both of these classes are entities that we store in the database so I would like to add a functionality to be able to delete these entities from the database for this let's add let's say the delete property which is a boolean we set it when the entity is deleted and the delete function also that's called the property deleted okay so in this function we would delete the entity then we would do the same for the user basically the functionality will be repeated so in here we can use the mixing pattern to share this functionality between the car and the user so let's do this I'm creating a function called deletable as the argument it takes the base class which in our case would be the car and the user classes let's call the argument base class or just base we should describe this argument for this let's make the deletable function generic because we would like to accept any class that's called the generic type parameter base class and describe base as base class now we need to make sure that the base class type is actually a class that can be constructed or instantiated so let's create a helper type let's call it constructible and here we define a constructor function by appending the new keyboard to the function this description this function takes some arguments like it can be any argument and returns the instance of the class it's constructing let's call this type class instance but we can't get this type out of nowhere so we need to define it as a generic type parameter in here so let's call this type class instance and return it from the constructor function ok now that we have the type which describes any constructible class we can use this type to constrain the base class to make sure that base class is actually a class that we can construct for this we use the extends keyword and then we type constructible and as the generic type parameter as instance let's provide like an empty object okay now from this function we should return a new class let's use an anonymous class which extends our base class this one and in this class we add the delete functionality now our anonymous class has all the features of the base class because it extends it and also the delete functionality so now let's remove the delete functionality from both car and user and use the deletable mixin function to make car and user classes deletable for this I type Const the first let's make the card eligible okay let's make the user deletable as well so now we have the deletable car and the deletable user classes let's say we would like to add another class the profile which will hold the data about the user and the third car profile class will have property user which should hold the instance of the user class how do we describe that the user property is an instance of the used deletable user class if the little user was defined as a basic as a normal class like the class user or class car we could describe the instance like this deletable user but in this case we create a class and assign it to the deletable user variable so it's not a type it's a variable so we cannot use a variable in place of the type so in order to get the instance type of the deletable user variable we do the following let's call this type deletable user instance then we say instance type and we provide the type of the static side of the deletable user class for this we type type of the little user and now we can use this deletable user instance type to describe the user instance in here we should do the same with the deletable car instance type okay finally let's instantiate the profile and assign the instance of the user of a user oh not the user it expects the deletable user instance so we type new the little user and the writable user expects a name so let's name the user John and we create the car for John let's call the car Ferrari okay that's it this is one of the most popular use cases for the instance type finally let's talk about this type this type doesn't transform one type into another as the other utility types do this type acts as a marker that allows us to specify the type of this keyboard in an object let's see the first example and here we have interface my object that has one method say hello and we've got another interface my object this which we use to describe the disk award of our object and the disk keyboard should have the hello world method which returns a string then we create my object object and describe this object using the my object interface we define them here then we use this type marker to describe the this keyboard using them my object this interface why would we describe the disk award apart from the main object well maybe we would like to set the context of this later in our program let's check how let's open this code in an editor in here we've got the same code that I showed you on the slide this is the object we have created let's use the bind method on the say hello method to set the context of this let's set these to the object that has the hello world method okay finally let's call sake hello let's log it now let's compile the file and run the jas that we've got and we've got the hello world string that we set in here now let's check the example from the typescript handbook in here I have opened there this type section the handbook says that we have to compile this code with no implicit this option otherwise this type won't work let's copy this code into the editor okay so what we've gotten here first we have the definition of the type called object descriptor which is a generic type which takes two generic type parameters D and M this type describes an object these two properties data and methods the type of data is D and the type of methods is M and this type with D and M so it's an intersection of T and M so basically what this says is the data property should be an object of type D and methods property should be an object of type m and the disk awards in methods should be set to an object that has a shape of both D and M combined that we've got the function called make object it takes the same to generic type parameters G and M it takes the desk argument which is described as object descriptor this one this entity and M parameters from the functions generic type parameters finally this function returns the intersection of D and M so it returns the object with the properties and methods of balls D and M combined now let's see what this function does it creates the data object if the data property is set on the desk object we take the data from the desk otherwise we take an empty object we do the same with the methods finally this function returns a new object is all the properties of data and methods objects finally we tell typescript that the return value has type of D and M combined okay later on we create an object using this make object function we set the data to an object which has two properties x and y and the metas object is set to an object with the move by method from here typescript is able to infer the types of D and M it infers the type of the data object as D and the type the structure of the metal object as M finally it is able to infer the type of this object since the object descriptor type describes the methods object as M which is the type in here and it uses the this type marker to set the this keyword to the intersection of D and M so it's the intersection of the object and methods object and finally this has the type the structure of data object with X&Y and the methods object visit the move by method type script was able to infer all of this through the definitions above through these definitions finally for the dis type to work please make sure that the option called no implicit dis is enabled okay that's it thanks for watching if you liked the video please click the like button have a nice day
Info
Channel: Dmytro Danylov
Views: 28,808
Rating: 4.9692307 out of 5
Keywords: TypeScript, TypeScript Utility Types, TypeScript InstanceType, TypeScript Pick, TypeScript Omit, TypeScript Exclude, TypeScript Extract, TypeScript ThisType, TypeScript Partial, TypeScript Advanced Types
Id: Fgcu_iB2X04
Channel Id: undefined
Length: 35min 32sec (2132 seconds)
Published: Mon Oct 07 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.