The TypeScript Library You've Been Waiting For

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I just came across this library in typescript and it is called the it's still in beta but what I've seen so far it's great it allows you to write functional code in typescript but the selling point at least for me is not the fact that it is functional but rather how it can simplify your code provided you understand the library of course now if you come here to their official website you'll see that they have this make the hard things easy as your application grows effect scales with it keeping your code simple and maintainable now I'm not entirely sure about the keeping your code simple because the vast majority of examples I stumbled across online and even from their official examples they are't simple and in fact I would say they are over engineered which reminds me a lot of rxjs where people end up throwing rxjs at absolutely every single problem in code and it ends up being extremely complicated and that is true for effect as well I would say use it aspiring do not make your whole application with effect or even with rxjs it really doesn't make sense when the language already has great features anyway if you come to the do you'll see that they have this warning the documentation is currently under construction and some sections may be incomplete or subject to changes so as I said since the library is in beta you'll see that the documentation is really lacking sure they have guides on the essentials Ser management and whatever but if you try looking for examples or documentation for their plugins like the HTTP Plus Plugin or the schema plugin you'll see that there is basically nothing whatsoever and the documentation that you do find in their GitHub repository is quite outdated if you copy and paste a sad from say the HTTP library from their official documentation you'll see that it's not going to work because it's outdated and I guess they changed the API of the library and so it no longer works as it once used to but anyway let's take a look at this Library I have two examples for this I have this valid agent B an object function which as we can see we use a triy catch we par a value we check if it is a record if it isn't a record we return an error otherwise we return the par Json and if we get an error well we just catch that error of course we're not checking for the instances of the error but it's just a few lines of code so it doesn't really matter and then to call this function all you do is get the result so this is the result and then you can switch upon the success Boolean property so in the case that it is true you get access to data in the case that it is false you get access to error so this is perhaps the best way to handle errors in typescript you use a discriminated Union and then you have the discriminator so true you get access to data false you get access to error and why do we do this well to let the caller know that the function can result in an error throwing errors or raising exceptions is an antipattern and you shouldn't do that whatsoever sure there are specific instances where that makes sense but in general enal you shouldn't throw errors now you can see this Behavior or at least a robust handling of errors in other languages for example in go you have the topples if we were to replicate this in typescript you could say type result is equal to and then a topple and the first one is a record of a string or unknown and then you could say this could be null makes sense because it could result in an error so you do not get access to this and then you have the error itself which could be a string or null likewise and so here you would return a topple with the parse Json and then the error would be null so in this case for example if it isn't a record you would return a topple with null and then the message itself value is not a valid Json object for example then you have rust rust uses the result type so you can have result and then T and then e where T represents the success value and E represents the error value type as simple as that so in a name to provide robust error handling libraries like effect came around now sure we can use discriminated unions for this but notice how much code we're writing we have to define the type so Json validation result you need to provide the discriminator so you need to ensure that success is true and success is false in the other one and then you need to Define this and it could get quite messy making sure that all throughout your code base you're using this and you're not changing this to say success so you keep data instead of success and this could be failed for example all of those things can be simplified with the effect Library so here we're using effect so we say import effect from effect and then we create the function so valid ajon object we take in a value and this returns an effect of the success property so this is the case where this is successful and then we pass in the errors so we pass in a union of all of the possible errors in this case I did it explicitly but again it doesn't matter this is quite easy to refactor now here we say try catch we passing the same code so this is the same logic exactly the same in fact it spans basically the same lines but instead of returning well an object success fals error then the string what we do is simply say effect. fail and this is well type save the function will obviously check against this type so if we were to pass in a string instead of an error as we can see we get an error here which is the same as if we were to do it here if we were to pass in a number instead we get the error so functionality wise it is pretty much the same but it is simplified because you do not have to create these discriminating Union and then apply the logic accordingly all you need to do is Define the return type like this so remember the first argument is when it is successful the second one is when it is an error and then you just call effect. fail or effect succeed now here we catch the error we say effect. fail if the error is an instance of syntax error or of error we just return the error otherwise we create a new error saying unknown error and now how can we call it since we're not using an object with a discriminator now for this what we do is pipe through so we can pass in different effects and we can do whatever we want there so for example here we invoke the function and then we say that pipe and then we can say effect that match and then we can pass in an object to this function and this object must contain these two so the unsuccess Callback and the unfail Callback so we get access to the value when this is successful so when we say effect that succeed and as we can see the type is correctly inferred as record of a string or known now in the case of an error we get access to the union either error or syntax error and then we can do whatever we want Within These callbacks now to run the function in fact when you just invoke this function and you get back all of these log you're not invoking it per se you need to tell effect hey we're going to be running this function so you can say effect. run sync why sync because it is a synchronous function it is not a sync so run sync now this is not entirely functional because you know the functional Paradigm is based on declarative over imperative code and here this is quite imperative we must say try then catch we must get the error then we must return effect that fail we're doing everything very imperatively and you can in fact refactor this to be more declarative using the effect Library the reason why I didn't do that for this example is because I wanted to show you how easy it is to integrate it with your code and you can keep the same function now if you do not want to embrace the functional paradig and you want to keep writing your code like this which is way more imperative you can perfectly do that in fact you can replace all of your discriminating functions to use an effect instead and that's a perfect use case but the library offers more than just effect that fail or effect that succeed and that is again making your code more declarative so if we were to change this to be more declarative how can we achieve that well for that what we can do is create another function so function and then we can say with effect and then we return an effect. try and here we get access to try so we import a synchron new side effect into a pure effect value translating any thrown exceptions into typed failed effects creating with effect. fail then we get access to try map so with this we can change the value in the pipe then try map promise but for promise and then try promise so pretty riment now here we can say try and then we can pass in the options so we can say try and then catch which is pretty much the same as we are doing here but instead of using this try and catch we use functions and then what we can do is Paris djon so let's break it down in different steps so it is also more declarative so we get the value which is a string and then we just pass into json. parse and then we just return the parse Json as simple as that now here we can say catch and then we get access to the errors and so what we can do is just return effect. fail so now let's try typing this effect. effect the result is unknown and then the errors could be syntax error or error but notice how we get an error and why because we're returning an effect to what returns an effect so as we can see this returns an effect that effect of never because it doesn't succeed and then syntax error so for that what we can do is just return error instance of syntax error and if so return this and as we can see the error went away so now we can come here and we can say with effect and we pass in this string for example and then we can say pipe and now if we say effect map so we change this as we can see the value is of type unnown and this in fact will only be executed if it succeeds now if we want to get access to the errors we can effect do catch and then we can say catch all and then we get access to the error and as we can see it is typed as syntax error or error but now let's change this up so we know that the map results in a new value so the state or whatever is being passed to the chain is effectively immutable meaning that the only way we can mutate it is via this effect. map calls so now here we need to check if it is a record and if so we want to return the record or we want to return an error so that that we can handle it in the pipe so for that what we can do is actually say is record and then we pass in the value and if it is we just return the value but what about the error what if it isn't a record you might be inclined to just say effect that fail and then we pass in a new error for example it's not a record but if we were to say effect. map and then we get access to the value once again as we can see the value is record string or known or an effect of never and then error which is not what we want we do not want to handle the errors when we're mapping so for that we need to change this to a flat map and then we need to say effect. succeed and then we pass in the value and as we can see the went away and now if we take a look at value value is correctly inferred as a record and how come flat map fixed this issue for us well that is because as we know flat map in JavaScript flattens an array so it normalizes to put it like that the array the same thing happens for this it is taking the effect that fail and the effect that succeed and with the flat map it is able to correctly take those effects so these two effects and map them accordingly so in this case when we call map we now get access to the value and that's pretty much it now to run it well of course you would say run sync and to handle the error you can say effect. catch and then you catch the errors so error and if we take a look again it is syntax or error or we can say effect that match and then we get access to a failure and un success so we can essentially just copy and paste this here and now this is the effect way of doing things now let's see if it still works if I comment all of this out and then run it as we can see we get success what if it is an error so just an empty one and we run this we get error Json pars error unexpected and offline okay so I just cleaned up the code and as we can see they are pretty much the same they span pretty much the same lines and well the logic is the same now I moved the logic here of the flat map with the E Record validation to these functions since well that pertains to the function and not to the color in this case the color should only worry about accessing the errors and will the value in the case of success now is it worth using effect Ts for just this probably not as we can see this more complex plus you need to learn the library but even if you just stick to the basics like this you shouldn't have any problems whatsoever and it is still very readable at a glance to understand this code it should take you just a quick read of the documentation and I believe you're good to go now let me show you one last example so this is for an HTTP request so let's take a look at the code without effect as we can see get to this we can pass in Rich rise which is of type number and this is going to return a promise of Todo now what is this to-do well it's just an object ID to-do completed and user ID so here we have a TR catch block we fetch thei jason.com toodo then we try to retrieve the Json from the body of the response and I say we try to do so because it might not return adjacent body so this could result in an error and then we parse the data so we're using S for this where we get back the to-do so an array of to-do schema the total keep and limit this is for pagination and if all of this is successful we just return the to this as simple as that now in the case of an error we simply check if R TR is greater than zero then await new promise we pass in resolve and just set time out to resolve when 100 milliseconds have passed so this is like a delay and then we return get to do we pass in the previous ret rise minus one and that's it and then we just throw the error if the ret rice have already been exhausted and then here we must wrap this in a TR cach we say cons to do is equal to a weight get to doce then cons completed to do we just filter the to do where the completed property is true and then we just lock them so again what can we notice from this code well it is quite imperative we have to Define everything ourselves step by step and we need to delve somewhat into the implementation details of course all of this is substracted from us so the fetch function the Json and even the S schema parsing all of this is abstracted but even then it is quite imperative now let's take a look at the effect code so here we can pass in retrice same thing and this returns an effect where the result is an array of to-do and then we have the errors so we have the sought error we have the response error and we have a request error so what happens if we cannot make the request or some reason then we get access to request error what happens if we get an error in the response then response error and finally what if the response body we got back from the API it's not in the shape we needed then it is going to result in a s error so here we say return HTTP do request.get and we pass in the link now this comes from the library and as we can see import all this HTTP from at effect SL platform now this is going to basically return to us an effect so we can pipe this through so we say that pipe then HTTP client. Fetch and then we can say effect. retry so this is going to retry doing this if it results in an error so here we can say schedule fixed 100 milliseconds and then times to dep pass the enrich rise and then we say HTTP response. Json so this is going to do this for us and then we say effect. flat map we get the response we say effect. try and then we try parsing the response so DJ somebody and if there's an error then we catch it and we know that it can only be a s error because s will only throw a set do s error in the case that this parsing fails and then we just map the response again and we retrieve the todos now we can simplify this and we can just say todos here and now well we can get rid of this line but that depends entirely on how you want to manage things do you want to lay out everything step by step so this should only worry about parsing the data and then we have the line for retrieving the data we need again that depends entirely on you so we can remove it if we want now to call it all we need to do is say a wait C to this then do pipe and then we just filter the toos where completed is equal to true so the same logic as here and then effect. top now you might be wondering what is this St well map is going to replace the value you get in the chain similar to mapping over an array you're going to get back a new value tap is just a way for you to tap in without affecting the result value so whatever you return from here cannot be accessed outside of this callback pretty much so here you can perform side effects that shouldn't affect the result value or well in our case we can just lck the completed todos and as we can see is just an array of to do so this will be executed if this doesn't result in an error and then we say effect that run promise and that's it now again if you want to handle the case of errors and whatnot you can leave it like this so effect that up and then you could have if effect that and then catch all and here you get the errors and again this is going to give you this Union s error response error or request error or you can use effect. match whichever you prefer and that's pretty much it the functionality is pretty much identical you're going to get back the same result but the benefit you get with this is not only the type safety which is incredibly important but also the Simplicity and how everything is perfectly laid out you do not have to worry about how this works under the hood or how this works you can be rest assured that effect will handle all of this for you internally you only worry about the results so I invite you to check out the documentation play around with this Library see what works see what doesn't work and perhaps consider it to integrate it with your applications anyway this wraps up the video I hope you enjoyed the video and if you want to see more content like this make sure to subscribe I'll see you in the next one yeah
Info
Channel: Lucas Barake
Views: 1,168
Rating: undefined out of 5
Keywords:
Id: X98vwMYxRXw
Channel Id: undefined
Length: 18min 59sec (1139 seconds)
Published: Sun Mar 31 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.