{"id":7084,"date":"2019-05-29T22:07:09","date_gmt":"2019-05-29T22:07:09","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=7084"},"modified":"2019-10-05T17:45:25","modified_gmt":"2019-10-05T17:45:25","slug":"method-overloading-in-typescript","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/method-overloading-in-typescript\/","title":{"rendered":"Method overloading in Typescript"},"content":{"rendered":"<p>Method overloading within TypeScript feels slightly strange, especially if you&#8217;re coming from a language such as C#. <\/p>\n<p>In essence we declare the overloads but only have a single implementation which should handle the alternate arguments from the declared overloads by checking the types passed in. Don&#8217;t worry, we&#8217;ll look at an example which will make this clear.<\/p>\n<p>The first thing to know about TypeScript overloads is if we declare overloads with the same number of arguments in the methods, these will be transpiled to JavaScript and the static types of the arguments is lost. <\/p>\n<p>In other words, if you have <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass Options {\r\n   static if&lt;T&gt;(value: T, condition: boolean): void {\r\n   }\r\n   static if&lt;T&gt;(value: T, numberParameter: number): void {\r\n   }\r\n}\r\n<\/pre>\n<p>the type information would be lost when transpiled, effectively meaning both methods would look like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nstatic if(value, condition);\r\n<\/pre>\n<p><strong>So how do we do method overloading in TypeScript?<\/strong><\/p>\n<p>We can create method overloads with different numbers of arguments within TypeScript, but we &#8220;declare&#8221; the method signatures without implementations, for example<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass Options {\r\n   static if&lt;T&gt;(value: T, condition: boolean): void;\r\n   static if&lt;T&gt;(value: T, numberParameter: number, stringParameter: string): void;\r\n\r\n   \/\/ implementation to follow\r\n}\r\n<\/pre>\n<p>As can be seen we have two overloads of the <em>if<\/em> method taking two and three arguments respectively, but these methods have no implementation. Instead we need to create another overload which can take all the arguments. <\/p>\n<p>In this case we have a method with two arguments and one with three, hence our implementation needs to take three arguments. We then need to either match the argument types (if all overloads take the same type for any argument) or handle different types via a union or an <em>any<\/em> type and then check the type passed into the method using typeof or instanceof. <\/p>\n<p>So for example, here&#8217;s an implementation of a method which can handle the types passed to either of the &#8220;declared&#8221; overrides <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nstatic if&lt;T&gt;(value: T, stringOrNumberParameter: any, stringParameter?: string): void {\r\n   if (stringOrNumberParameter &amp;&amp; typeof stringOrNumberParameter == &quot;number&quot;) {\r\n      \/\/ handle the second argument as a number\r\n   }\r\n   else {\r\n      \/\/ handle the second argument as a string\r\n   }\r\n}\r\n<\/pre>\n<p>Notice how the third argument needs to be optional or have a default so that we can still use the two argument overload.<\/p>\n<p>Hence, we end up with the following<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass Options {\r\n   static if&lt;T&gt;(value: T, condition: boolean): void;\r\n   static if&lt;T&gt;(value: T, numberParameter: number, stringParameter: string): void;\r\n    \r\n   static if&lt;T&gt;(value: T, stringOrNumberParameter: any, stringParameter?: string): void {\r\n      if (stringOrNumberParameter &amp;&amp; typeof stringOrNumberParameter == &quot;number&quot;) {\r\n         \/\/ handle the second argument as a number\r\n      }\r\n      else {\r\n         \/\/ handle the second argument as a string\r\n      }\r\n   }\r\n}\r\n<\/pre>\n<p>We can implement overloads with the same number of arguments, within TypeScript. Again the types are lost once transpiled, but let&#8217;s take this example<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nfunction run(option: null): null;\r\nfunction run(option: number): number;\r\nfunction run(option: string): string;\r\nfunction run(option: any): any {\r\n  if(typeof option == &quot;string&quot;) {\r\n    \/\/ string implementation\r\n  }\r\n}\r\n<\/pre>\n<p>which again gets transpiled without types to<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nfunction run(option) {\r\n}\r\n<\/pre>\n<p>however during development the types are respected. In such scenarios one might also use unions, such as<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nfunction run(option: string | number | null) {\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Method overloading within TypeScript feels slightly strange, especially if you&#8217;re coming from a language such as C#. In essence we declare the overloads but only have a single implementation which should handle the alternate arguments from the declared overloads by checking the types passed in. Don&#8217;t worry, we&#8217;ll look at an example which will make [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[46],"tags":[],"class_list":["post-7084","post","type-post","status-publish","format-standard","hentry","category-typescript"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7084","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=7084"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7084\/revisions"}],"predecessor-version":[{"id":7501,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7084\/revisions\/7501"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=7084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=7084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=7084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}