{"id":2027,"date":"2024-04-03T16:36:51","date_gmt":"2024-04-03T23:36:51","guid":{"rendered":"https:\/\/www.angulartraining.com\/daily-newsletter\/?p=2027"},"modified":"2024-04-03T16:36:52","modified_gmt":"2024-04-03T23:36:52","slug":"understanding-angular-typescript-types","status":"publish","type":"post","link":"https:\/\/www.angulartraining.com\/daily-newsletter\/understanding-angular-typescript-types\/","title":{"rendered":"Understanding Angular\/Typescript types"},"content":{"rendered":"\n<p>First, some news: I&#8217;m running a <a href=\"https:\/\/courses.angulartraining.com\/course\/fundamentals-angular\" target=\"_blank\" rel=\"noopener\" title=\"\">public 5 half-day online Angular class<\/a> during the week of April 22nd. It&#8217;s the perfect class if you&#8217;re new to Angular or have some experience and want to ensure you know about all the fundamentals. It&#8217;s the ideal class to prepare for the <a href=\"https:\/\/courses.angulartraining.com\/course\/angular-level-1-certification-exam\" target=\"_blank\" rel=\"noopener\" title=\"\">Angular Level 1 certification<\/a> exam.<\/p>\n\n\n\n<p>On a side note, I can give private talks for your company or dev team on any topic, including Signals, the future of Angular, and more. Just email me for more info if you&#8217;d like to get such a talk planned in the future.<\/p>\n\n\n\n<p>Today, I want to cover a tricky topic for many developers I interact with: Reading and understanding Typescript type definitions from the Angular framework.<\/p>\n\n\n\n<p>For instance, let&#8217;s look at the type definition of the <a href=\"https:\/\/angular.io\/api\/router\/CanActivateFn\" target=\"_blank\" rel=\"noopener\" title=\"\"><code>canActivate<\/code> function<\/a>:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"625\" height=\"88\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image.png\" alt=\"\" class=\"wp-image-2028\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image.png 625w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-300x42.png 300w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>We can tell <code>CanActivateFn<\/code> is a function because:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The Angular team uses the <code>Fn<\/code> suffix as a convention for all functions<\/li>\n\n\n\n<li>The type signature is <code>( params ) =&gt; returnType<\/code>, which is how TypeScript defines types for functions. The arrow symbol <code>=&gt;<\/code> is key there.<\/li>\n<\/ol>\n\n\n\n<p>So, in that case, the function has two parameters, <code>route<\/code> of type <code>ActivatedRouteSnapshot<\/code>, and <code>state<\/code> of type <code>RouterStateSnapshot<\/code>. The function returns a type <code>MaybeAsync&lt;GuardResult><\/code>.<\/p>\n\n\n\n<p>Here is what the type definition of <code><a href=\"https:\/\/angular.io\/api\/router\/MaybeAsync\" target=\"_blank\" rel=\"noopener\" title=\"\">MaybeAsync<\/a><\/code> looks like:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"593\" height=\"47\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-1.png\" alt=\"\" class=\"wp-image-2029\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-1.png 593w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-1-300x24.png 300w\" sizes=\"auto, (max-width: 593px) 100vw, 593px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>What does that mean? <code>MaybeAsync&lt;T><\/code> is a generic type, which means it works with any number of types, referred to as <code>T<\/code> here. You can see <code>T<\/code> as a type variable that gets replaced with an actual value decided when we use that type. For instance, if I end up using <code>MaybeAsync<\/code> on a <code>string<\/code>, <code>T<\/code> becomes <code>string<\/code>, and our type definition means:<\/p>\n\n\n\n<p><code>type MaybeAsync&lt;string&gt; = string | Observable&lt;string&gt; | Promise&lt;string&gt;<\/code><\/p>\n\n\n\n<p>So <code>MaybeAsync&lt;string&gt;<\/code> can be either a <code>string<\/code>, an <code>Observable<\/code> that will return a <code>string<\/code>, or a <code>Promise<\/code> that will return a <code>string<\/code>. That&#8217;s because the | character defines a <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/union-types-in-typescript\/\" target=\"_blank\" rel=\"noopener\" title=\"\">union type<\/a> and can be seen as a logical OR. In other words: <\/p>\n\n\n\n<p><code>MaybeAsync&lt;string&gt; IS A string OR Observable&lt;string&gt; OR Promise&lt;string&gt;<\/code>.<\/p>\n\n\n\n<p>Now, in the case of our <code>CanActivate<\/code> function, the return type is <code>MaybeAsync&lt;GuardResult&gt;<\/code>. On <a href=\"https:\/\/angular.io\/\" target=\"_blank\" rel=\"noopener\" title=\"\">angular.io<\/a>, most types are clickable (a lot less on <a href=\"https:\/\/angular.dev\/\" target=\"_blank\" rel=\"noopener\" title=\"\">angular.dev<\/a> for now). If I click on <code><a href=\"https:\/\/angular.io\/api\/router\/GuardResult\" target=\"_blank\" rel=\"noopener\" title=\"\">GuardResult<\/a><\/code> on <a href=\"https:\/\/angular.io\/api\/router\/CanActivateFn\" target=\"_blank\" rel=\"noopener\" title=\"\">this page<\/a>, I get to the following documentation entry:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"421\" height=\"55\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-2.png\" alt=\"\" class=\"wp-image-2030\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-2.png 421w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-2-300x39.png 300w\" sizes=\"auto, (max-width: 421px) 100vw, 421px\" \/><\/figure>\n<\/div>\n\n\n<p>So a <code>GuardResult<\/code> is either a <code>boolean<\/code> or a <code>UrlTree<\/code>. This tells us that a <code>CanActivate<\/code> function can return six possible different types:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>a <code>boolean<\/code>, an <code>Observable<\/code> of a <code>boolean<\/code>, a <code>Promise<\/code> of a <code>boolean<\/code><\/li>\n\n\n\n<li>a <code>UrlTree<\/code>, an <code>Observable<\/code> of a <code>UrlTree<\/code>, a <code>Promise<\/code> of a <code>UrlTree<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>In the past, the <a href=\"https:\/\/v15.angular.io\/api\/router\/CanActivateFn\" target=\"_blank\" rel=\"noopener\" title=\"\">documentation would list the six types inline<\/a> as follows, which is the same thing but a little harder to read. Additional types have been added in Angular 16 to improve the readability of such framework APIs:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"912\" height=\"92\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-3.png\" alt=\"\" class=\"wp-image-2031\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-3.png 912w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-3-300x30.png 300w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-3-768x77.png 768w\" sizes=\"auto, (max-width: 912px) 100vw, 912px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Another tricky thing with types is that several features of the Angular framework support different options, resulting in multiple types of signatures. You can look at the <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/rxjs-and-signals-interoperability\/\" target=\"_blank\" rel=\"noopener\" title=\"\">toSignal<\/a> function for such an example &#8211; there are <a href=\"https:\/\/angular.io\/api\/core\/rxjs-interop\/toSignal#overloads\" target=\"_blank\" rel=\"noopener\" title=\"\">5 different overloads<\/a> in that function signature, the most basic one being:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"743\" height=\"63\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-4.png\" alt=\"\" class=\"wp-image-2035\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-4.png 743w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/04\/image-4-300x25.png 300w\" sizes=\"auto, (max-width: 743px) 100vw, 743px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>As an exercise, I invite you to examine <a href=\"https:\/\/angular.io\/api\/core\/rxjs-interop\/toSignal#overloads\" target=\"_blank\" rel=\"noopener\" title=\"\">the 5 overloads<\/a> and try to understand where they come from and why they make sense.<\/p>\n\n\n\n<p>If you encounter any other tricky type you can&#8217;t decipher, please send it my way, and I&#8217;ll be happy to cover it in a future newsletter entry.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>First, some news: I&#8217;m running a public 5 half-day online Angular class during the week of April 22nd. It&#8217;s the perfect class if you&#8217;re new to Angular or have some experience and want to ensure you know about all the fundamentals. It&#8217;s the ideal class to prepare for the Angular Level 1 certification exam. On [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,3],"tags":[],"class_list":["post-2027","post","type-post","status-publish","format-standard","hentry","category-angular","category-typescript"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2027","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/comments?post=2027"}],"version-history":[{"count":6,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2027\/revisions"}],"predecessor-version":[{"id":2038,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2027\/revisions\/2038"}],"wp:attachment":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/media?parent=2027"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/categories?post=2027"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/tags?post=2027"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}