{"id":7832,"date":"2021-08-04T01:10:00","date_gmt":"2021-08-04T06:10:00","guid":{"rendered":"https:\/\/upmostly.com\/?p=7832"},"modified":"2022-11-01T09:47:08","modified_gmt":"2022-11-01T14:47:08","slug":"type-checking-in-typescript","status":"publish","type":"post","link":"http:\/\/upmostly.com\/angular\/type-checking-in-typescript","title":{"rendered":"Type Checking In Typescript"},"content":{"rendered":"\n<p>Coming from a C# background, I don\u2019t tend to use Discriminated Unions a whole awful lot. By Discriminated Unions, I mean having a method that may take multiple different types, or may return multiple different types.<\/p>\n\n\n\n<p>If you\u2019ve come from a C# world, it\u2019s basically like method overloads when passing parameters into a method. And the other way, it allows you to make a method that could return one of many different types, that don\u2019t necessarily have to have an inheritance relationship between them.<\/p>\n\n\n\n<p>Let\u2019s see how this might work :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">class Plane {\n}\n\nclass Car {\n}\n\ngetVehicle() : Plane | Car {\n    \/\/Either of these are valid. \n    return new Plane();\n    \/\/return new Car();\n}<\/code><\/pre>\n\n\n\n<p>It\u2019s somewhat strange at first to get used to this ability if you\u2019ve never used a language that uses unions. Most developers would instead make a \u201cbase\u201d class of \u201cVehicle\u201d and make both Plane and Car inherit from Vehicle, and then you don\u2019t need a union. Which.. In my view is probably valid.<\/p>\n\n\n\n<p>But lets say you can\u2019t do that, and you are dealing with code that either returns a Plane or Car, *or* code that accepts a Plane or Car. You\u2019re going to need to know at some point, which one you have. Because if the objects were identical, you probably wouldn\u2019t need this union at all. Type checking in Typescript on the surface seemed easy, but I went down a bit of a rabbit hole through documentation and guides that weren\u2019t always clear. So I want to try and simplify it down all right here, right now.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using The TypeOf Operator<\/h3>\n\n\n\n<p>Javascript actually has a typeof operator itself that can tell you which type a variable is. As an example, we can do things like :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">let variable1 = 'abc';\nlet variable2 = 123;\nconsole.log(typeof variable1);\/\/Prints \"string\"\nconsole.log(typeof variable2);\/\/Prints \"number\"<\/code><\/pre>\n\n\n\n<p>But.. This isn\u2019t as helpful as you might think. Other than the fact that it returns the \u201ctype\u201d as a string, which is rather unhelpful in of itself, it doesn\u2019t work with complex types. For example :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">let myCar = new Car();\nconsole.log(typeof myCar);\/\/Prints \"object\"<\/code><\/pre>\n\n\n\n<p>For all custom classes (Which, in modern JavaScript you will have many), the return type is only ever object. That\u2019s because the typeof operator can only tell you which primitive type your variable is, but nothing beyond that.<\/p>\n\n\n\n<p>For this reason, while it may be helpful for telling strings from numbers, anything more, typeof is out!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using The InstanceOf Operator<\/h3>\n\n\n\n<p>That brings us to the instanceof operator. It\u2019s actually rather simple! We can just change our code to work like so :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">let myCar = new Car();\nconsole.log(myCar instanceof Car);\/\/Prints true<\/code><\/pre>\n\n\n\n<p>Works well and we can now tell if our variable is an instance of a car. But there is a caveat, and it\u2019s around inheritance. Consider the following code :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">class Car {\n}\n\nclass Honda extends Car {\n}\n\nlet myCar = new Honda();\nconsole.log(myCar instanceof Car);\/\/Prints true<\/code><\/pre>\n\n\n\n<p>Notice that even though our variable holds a \u201cHonda\u201d, it still returns true as a car. For the most part, this is how all programming languages work so we shouldn\u2019t read too much into this \u201climitation\u201d as it\u2019s really just polymorphism at play, but it\u2019s still something to keep in mind.<\/p>\n\n\n\n<p>Alas, we have an issue! A really smart developer has come along and said that interfaces are the new hip thing, and we should switch all classes to interfaces in our front end code. So we have this :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">interface Car {\n}\n\nlet myCar = {} as Car;\nconsole.log(myCar instanceof Car);\/\/Error 'Car' only refers to a type, but is being used as a value here.<\/code><\/pre>\n\n\n\n<p>This time around, we don\u2019t even get to run our code and instead we get :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">'Car' only refers to a type, but is being used as a value here.<\/code><\/pre>\n\n\n\n<p>What\u2019s going on here? Well.. the instanceof operator works with classes only, not interfaces. Gah! OK but actually there is a way to check this further!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using The As Cast Operator<\/h3>\n\n\n\n<p>Consider the following code (And yes I know it\u2019s a fairly verbose example, but should hopefully make sense!)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">interface Car {\n  carMake : string;\n}\n\nlet myCar = {carMake : 'Honda'};\n\nlet processCar = (car : object) =&gt; {\n  \/\/Some other code. \n  if(car as Car){\n    console.log((car as Car).carMake);\n  }\n}\n\nprocessCar(myCar);<\/code><\/pre>\n\n\n\n<p>Notice how we can cast our variable to a Car, and check if it has a value (by using a truthy statement, it will be undefined otherwise). Casting is actually a great way to determine whether variables are instances of an interface.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using Typescript Type Guards<\/h3>\n\n\n\n<p>One thing I want to point out about the above code is that we have had to actually cast the car twice. Notice that inside the console log, we had to cast again for intellisense to pick up we were using a Car.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">console.log((car as Car).carMake);<\/code><\/pre>\n\n\n\n<p>Typescript has a way to deal with this however. It\u2019s called \u201cType Guards\u201d, and it allows you to write code that will not only check an object is a given type, but that Typescript from that point on can treat the variable as the type.<\/p>\n\n\n\n<p>For example, we can create a custom type guard like so :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">function isCar(car : any): car is Car{\n  return (car as Car) !== undefined;\n}<\/code><\/pre>\n\n\n\n<p>The magic sauce here is the return type. It\u2019s actually \u201ccar is Car\u201d. That tells Typescript that should this return true, the input variable can be treated as a Car from this point onwards. This allows us to change our code to instead be :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"jsx\" class=\"language-jsx\">let myCar = {carMake : 'Honda'};\n\nlet processCar = (car : object) =&gt; {\n  \/\/Some other code. \n  if(isCar(car)){\n    console.log(car.carMake);\n  }\n}\n\nprocessCar(myCar);<\/code><\/pre>\n\n\n\n<p>Notice how inside our console log, we didn\u2019t have to cast again to have it act as a car.<\/p>\n\n\n\n<p>This is a really important concept when talking about type guards. It\u2019s not just a way to create a nice fancy method that can be used to check types, it actually allows Typescript to start treating what could be an unknown object type, as a very specific one within that code block.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Coming from a C# background, I don\u2019t tend to use Discriminated Unions a whole awful lot. By Discriminated Unions, I mean having a method that may take multiple different types, or may return multiple different types. If you\u2019ve come from a C# world, it\u2019s basically like method overloads when passing parameters into a method. And [&hellip;]<\/p>\n","protected":false},"author":131,"featured_media":7835,"comment_status":"open","ping_status":"open","sticky":false,"template":"post-tutorial-new.php","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[150],"tags":[],"class_list":["post-7832","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular"],"acf":[],"_links":{"self":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts\/7832","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/users\/131"}],"replies":[{"embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/comments?post=7832"}],"version-history":[{"count":3,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts\/7832\/revisions"}],"predecessor-version":[{"id":13407,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts\/7832\/revisions\/13407"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/media\/7835"}],"wp:attachment":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/media?parent=7832"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/categories?post=7832"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/tags?post=7832"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}