{"id":20607,"date":"2023-08-01T10:16:56","date_gmt":"2023-08-01T08:16:56","guid":{"rendered":"https:\/\/www.oimmei.com\/typescript-altri-5-trucchi-per-lo-sviluppo\/"},"modified":"2025-08-06T11:21:59","modified_gmt":"2025-08-06T09:21:59","slug":"typescript-more-5-tricks-for-development","status":"publish","type":"post","link":"https:\/\/www.oimmei.com\/en\/typescript-more-5-tricks-for-development\/","title":{"rendered":"TypeScript: 5 More Tricks for Development"},"content":{"rendered":"\r\n<p class=\"wp-block-paragraph\">Are you a web developer? Did you happen to work on a fairly complex JavaScript project, such as a <a href=\"https:\/\/nodejs.org\/en\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Node.js<\/a> server or a nice and complicated <a href=\"https:\/\/reactjs.org\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">React<\/a> website? Have the limitations in the programming language ever caused you to lose a lot of time and sanity in order to track down particularly sneaky bugs?<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Well, all of the above happened to us. Many times, actually. Enough to make me wonder if there is any better tool for developing and maintaining web projects. Something that makes it easier to find errors while using data structures, for instance.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Luckily, the answer is <em>yes<\/em>, and this tool is <a href=\"https:\/\/www.typescriptlang.org\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">TypeScript<\/a>! Open source syntactical superset of JavaScript developed mostly by Microsoft, TypeScript adds to every browser\u2019s favorite programming language a lot of new tools and features, mainly static typing, to make web projects easier to build and maintain.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">You most likely already know all of this, especially if you often hang out on this blog. Not only because of the <a href=\"https:\/\/css-tricks.com\/the-relevance-of-typescript-in-2022\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">incredible popularity<\/a> reached by TypeScript in the last few years, but also because right on this website there\u2019s already <a href=\"https:\/\/www.oimmei.com\/en\/typescript-5-tricks-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">an article of mine<\/a> discussing some interesting features of this language. Back when I wrote it I talked about a potential sequel, and here it pops up just like a \u201cCannot read property of undefined\u201d error in a JavaScript program.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Let\u2019s get into it, then. Five sections, five TypeScript tools you may or may not know, with full examples and links to the <a href=\"https:\/\/www.typescriptlang.org\/play\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">official playground<\/a> for version 5.1. Here we go.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Tuple<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This one is really simple, but I bet it\u2019ll be new to somebody.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Everyone who works with TypeScript knows how to statically type arrays: you just set the type of the elements, and then add the square brackets afterwards.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">const numberArray: number[] = [];\r\n\r\n\/\/ Valid:\r\nnumberArray.push(1);\r\nnumberArray.push(2);\r\n\r\n\/\/ Not valid:\r\nnumberArray.push(\"string\");<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?#code\/MYewdgzgLgBGCuBbARgUwE4EF3oIYE8AuOJNdAbQF0YBeGKgbgFgAoVgenZgDVcAbAJYATQqwQoM2PPgB0AB3gQAFgAoAjAEpmLcWSkF5i1QCYtrDlwByIWADd+w0TtKScBhcpUAiaOgFgAcy8tIA\" target=\"_blank\" rel=\"noreferrer noopener\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">What\u2019s not so obvious is that you can use type definitions as a simple way to create <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tuple\" target=\"_blank\" rel=\"noreferrer noopener\">tuples<\/a> &#8211; already mentioned in the <a href=\"https:\/\/www.oimmei.com\/en\/typescript-5-tricks-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">previous article<\/a> -, meaning ordered lists of non-unique elements. Here\u2019s a tuple of three numbers.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">\/\/ Valid:\r\nconst numberTuple1: [number, number, number] = [1, 2, 3];\r\n\r\n\/\/ Not valid:\r\nconst numberTuple2: [number, number, number] = [];\r\n\r\n\/\/ Not valid:\r\nconst numberTuple3: [number, number, number] = [1, 2, 3, 4];<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=8&amp;ssc=61&amp;pln=1&amp;pc=1#code\/PTAEDUEMBsEsBMBcBYAUAYwPYDsDOAXUbAVwFsAjAUwCcAVYgB2koEZFQBtEimgGiLJVq-bkIC6oALycW-AEz8AzGIDcaNCFAA5TIQBuMBCgw4CAnnUbM57LoL7mhI+9QnSOq9ak079hpGhYeISiNPRMlIq2ocKODjFuMvJK-AAsqkA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The good thing about tuples is that, as you can see from the snippet, static typing allows TypeScript to validate the cardinality of the list, not just the type of its elements. This ensures that the data structure always contains exactly the elements you expect in the positions you expect.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Tuples have plenty of applications in JavaScript projects. In React, for instance, they\u2019re useful for defining <a href=\"https:\/\/react.dev\/learn\/state-a-components-memory\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">state variables<\/a> that keep in one simple structure a bunch of values tightly related to one another, so you can easily read and update it without making the related component too verbose, especially <a href=\"https:\/\/react.dev\/learn\/state-a-components-memory#meet-your-first-hook\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">with hooks<\/a>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Finally, it\u2019s worth pointing out that tuples can contain diverse data of any type, even complex ones &#8211; including other tuples, if you want to be creative!<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code\">interface ResponseBody {\r\n  title: string\r\n  content: string\r\n}\r\n\r\n\/\/ This tuple contains an HTTP code, a \r\n\/\/ response message and the response body.\r\nconst apiResponse: [number, string, ResponseBody] = [\r\n  200,\r\n  \"success\",\r\n  {\r\n    title: \"Title\",\r\n    content: \"Content\",\r\n  },\r\n];\r\n\r\n\/\/ Getting the items with a destructuring assignment\r\n\/\/ (https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/Destructuring_assignment).\r\nconst [statusCode, message, body] = apiResponse;\r\n\r\nconsole.log(statusCode);\r\nconsole.log(message);\r\nconsole.log(body);<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=23&amp;ssc=19&amp;pln=1&amp;pc=1#code\/JYOwLgpgTgZghgYwgAgEoQM4AcD2IMQBCOAJgJ7IDeAsAFDLJjBgA2EAXMhmFKAOZ0GCPJHCduvEANoBfOnQD0C5ABUAFsAyMArljbJh4OKC1wQyABIqVABQOkIAGmRxki5VEy58KALaYMOD4UMxJGNRRPbDwCZAAjUjIAOjpDbhcsYHRon04AbRBtXzjoZwl+Z2zvAmJyAF1kAF5kPMFkACYABk7HNoAiDG0EJAwMPt76KjaGJlYOZD6VZjZx6ftwCDEFgGERTbBVyZkJuoBueVolZABxCDAmKXCUZghfLQB3ZjUXZBJMHiGYG0kj4LlGwD4IH84HcyAAFGp7lgMOwlH8AG4QFg4LDQJK+HAAL2ALBYcCSOCgfAUmwAtABVADKChIOAQGAUAHUIHEFAApODouCMhC8LBgBToGDQTZIBQAeVxUDgYEpHIAIv8oIDgfwAPpwcGQ6FgACUKVoaTALW4Ku0GF2f2c-lGQSc8USDWacEyVRiEHOtFSMRwbCS2L4cNtQIdDlNgbSoYg4ZwkZdgWC8eD+CTKcjCXI8aAA\" target=\"_blank\" rel=\"noreferrer noopener\">Try it on the <\/a><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=23&amp;ssc=19&amp;pln=1&amp;pc=1#code\/JYOwLgpgTgZghgYwgAgEoQM4AcD2IMQBCOAJgJ7IDeAsAFDLJjBgA2EAXMhmFKAOZ0GCPJHCduvEANoBfOnQD0C5ABUAFsAyMArljbJh4OKC1wQyABIqVABQOkIAGmRxki5VEy58KALaYMOD4UMxJGNRRPbDwCZAAjUjIAOjpDbhcsYHRon04AbRBtXzjoZwl+Z2zvAmJyAF1kAF5kPMFkACYABk7HNoAiDG0EJAwMPt76KjaGJlYOZD6VZjZx6ftwCDEFgGERTbBVyZkJuoBueVolZABxCDAmKXCUZghfLQB3ZjUXZBJMHiGYG0kj4LlGwD4IH84HcyAAFGp7lgMOwlH8AG4QFg4LDQJK+HAAL2ALBYcCSOCgfAUmwAtABVADKChIOAQGAUAHUIHEFAApODouCMhC8LBgBToGDQTZIBQAeVxUDgYEpHIAIv8oIDgfwAPpwcGQ6FgACUKVoaTALW4Ku0GF2f2c-lGQSc8USDWacEyVRiEHOtFSMRwbCS2L4cNtQIdDlNgbSoYg4ZwkZdgWC8eD+CTKcjCXI8aAA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">playground<\/a><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Utility types: Readonly e NonNullable<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/utility-types.html\" target=\"_blank\" rel=\"noreferrer noopener\">Utility types<\/a>! Remember them? I already talked about a couple of these type modifiers in the <a href=\"https:\/\/www.oimmei.com\/en\/typescript-5-tricks-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">previous article<\/a>. Today we\u2019ll look at two more of them, often overlooked but far from useless.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/utility-types.html#readonlytype\" target=\"_blank\" rel=\"noreferrer noopener\">Readonly<\/a> is a modifier that creates a read only version of a given type. If you have the interface for an object, for example, this utility type can make sure none of the properties can be reassigned after the object is created.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">\/\/ Interface for an item with an ID and a title.\r\ninterface SomeInterface {\r\n  id: number\r\n\r\n  title: string\r\n}\r\n\r\n\/\/ SomeInterface object:\r\nconst someObject: SomeInterface = {\r\n  id: 1,\r\n  title: \"Title\",\r\n};\r\n\r\n\/\/ Readonly SomeInterface object:\r\nconst someReadonlyObject: Readonly&lt;SomeInterface&gt; = {\r\n  id: 2,\r\n  title: \"Readonly title\",\r\n};\r\n\r\n\/\/ Valid:\r\nsomeObject.title = \"Another title\";\r\n\r\n\/\/ Not valid:\r\nsomeReadonlyObject = \"Yet another title\";<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=24&amp;ssc=42&amp;pln=1&amp;pc=1#code\/PTAEEkDsBcFMCcBmBDAxrUiD29TMqAJZwC2oA7sQBZ4HgAitAJnqNMQDawB0AsAFCEYCFOlABlLCVhQ4SNBgDeA0ESYAuUJACuJAEYIBKtp1iaAztHhCA5gIC+R-iAlSZw+WKx6AVrFTQ6gKoWJCWoOZuAPK+-oGu0rIiCqAAvKDK-KqEGqAAjAA0xuzQXJoARAAqpuVF-PYA3E4uAEqwyEyhHACeCe5yohjefgFB-CFh0BFubR1d3TEj8bOdkD0APJKJHoMAfGkZxjmaAEx1qiVloOUr8yalsLUOTfwCLgBqyBzHApHSi3FuJcMOlygBBSBYaBUBD3LjlF5vMAAOShoAAbl8fvw-rBbmsFrEAgdygBNWBTfBQmG4YEIoA\" target=\"_blank\" rel=\"noreferrer noopener\">Provalo sul <\/a><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=24&amp;ssc=42&amp;pln=1&amp;pc=1#code\/PTAEEkDsBcFMCcBmBDAxrUiD29TMqAJZwC2oA7sQBZ4HgAitAJnqNMQDawB0AsAFCEYCFOlABlLCVhQ4SNBgDeA0ESYAuUJACuJAEYIBKtp1iaAztHhCA5gIC+R-iAlSZw+WKx6AVrFTQ6gKoWJCWoOZuAPK+-oGu0rIiCqAAvKDK-KqEGqAAjAA0xuzQXJoARAAqpuVF-PYA3E4uAEqwyEyhHACeCe5yohjefgFB-CFh0BFubR1d3TEj8bOdkD0APJKJHoMAfGkZxjmaAEx1qiVloOUr8yalsLUOTfwCLgBqyBzHApHSi3FuJcMOlygBBSBYaBUBD3LjlF5vMAAOShoAAbl8fvw-rBbmsFrEAgdygBNWBTfBQmG4YEIoA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This can look sort of useless, but think about all the times you deal with values that <em>should<\/em> be read only: objects that contain some sort of configuration parameters, <a href=\"https:\/\/react.dev\/learn\/state-a-components-memory\" target=\"_blank\" rel=\"noreferrer noopener\">the state of a React component<\/a>, <a href=\"https:\/\/redux.js.org\/tutorials\/essentials\/part-1-overview-concepts#immutability\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">the state of a Redux store<\/a> or data related to any library that relies on regular JavaScript comparisons in order to trigger some event in your application. Thanks to <strong>Readonly<\/strong>, TypeScript itself can help you deal with this data by throwing an error whenever you reassign a value that shouldn\u2019t be reassigned. It\u2019s like <strong>const<\/strong>, but deeper!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/utility-types.html#nonnullabletype\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">NonNullable<\/a> is a modifier that excludes <strong>null<\/strong> or <strong>undefined<\/strong> from a union type. I don\u2019t think this one needs much of an explanation: it\u2019s useful when you have a type, like the type of an interface property (you do remember you can access the type of a property, <a href=\"https:\/\/www.oimmei.com\/en\/typescript-5-tricks-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">right?<\/a>), that can be empty but you need to initialize it to a non-empty value.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">interface SomeInterface {\r\n  \/\/ In this interface, value may be empty.\r\n  value: number | null | undefined\r\n}\r\n\r\n\/\/ I'll initialize a variable I'll use as my value,\r\n\/\/ but this time I need it to not be empty.\r\n\r\n\/\/ Valid:\r\nconst val1: SomeInterface[\"value\"] = null;\r\n\r\n\/\/ Not valid:\r\nconst val2: NonNullable&lt;SomeInterface[\"value\"]&gt; = null;\r\n\r\n\/\/ Valid:\r\nconst val3: NonNullable&lt;SomeInterface[\"value\"]&gt; = 10;<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=16&amp;ssc=54&amp;pln=1&amp;pc=1#code\/JYOwLgpgTgZghgYwgAgMoHsC2ECS5rxLIDeAsAFDLID01yeyYAFsAM7KiSyIQA0yANzgAbAK4pMcAJ7IARigiYADmCkA6ClSFiIALmQhRmeVGQAfA6OHDzyUSAAmEGKAgOKAXwoVa9AOTWHCDAYMAiwABeKHCCcFBhssIoOAE2oqzR7Jgy2uK8PnSyomCMLOyh2PQGEG4cJWDoBugl8siKKure5L4AauEOuhQI6CCsJdoAjPoY2HhchBAA2gBEuRDLALrIALyW1gDcXb4Acs2xwsADQyNj5wBM+qcgx1bCcIkQADwzuPjcSCs1psAHw7PbCQ7kArIPoXK7kYajcYiADMjxGL2s7yS3ywv3mPEBInEILBEwADPsgA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Generic types: default type, constraints, conditional types<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Whoever worked with programming languages like <a href=\"https:\/\/en.wikipedia.org\/wiki\/Java_(programming_language)\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Java<\/a> or <a href=\"https:\/\/en.wikipedia.org\/wiki\/C_Sharp_(programming_language)\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">C#<\/a> &#8211; also known as <a href=\"https:\/\/www.reddit.com\/r\/ProgrammerHumor\/comments\/bnvojm\/c_is_just_microsoft_java\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Microsoft Java<\/a> &#8211; definitely knows what <a href=\"https:\/\/en.wikipedia.org\/wiki\/Generic_programming\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">generics<\/a> are. For anybody else, meaning all developers who still have some of their sanity, generics allow you to create software components that may accept a variety of different types, with the specific type provided by the component user, while still taking advantage of static typing.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">\/\/ Let's say you need to write a function that takes any input parameter \r\n\/\/ and returns it. Without generics, this is the best you can do.\r\nfunction identityAny(param: any): any {\r\n  return param;\r\n}\r\n\r\n\/\/ But *with* generics:\r\nfunction identity&lt;T&gt;(param: T): T {\r\n  return param;\r\n}\r\n\r\n\/\/ Valid:\r\nconsole.log(identity&lt;string&gt;(\"string\"));\r\nconsole.log(identity&lt;number&gt;(42));\r\n\r\n\/\/ Not valid:\r\nconsole.log(identity&lt;boolean&gt;(11));\r\n\r\n\/\/ You can use them for interfaces...\r\ninterface GenericInterface&lt;T1, T2&gt; {\r\n  param1: T1\r\n\r\n  param2: T2\r\n}\r\n\r\n\/\/ ...classes...\r\nclass GenericClass&lt;P&gt; {\r\n  prop: P\r\n\r\n  constructor(propValue: P) {\r\n    this.prop = propValue;\r\n  }\r\n\r\n  getProp(): P {\r\n    return this.prop;\r\n  }\r\n}\r\n\r\n\/\/ ...functions...\r\nfunction genericFunction&lt;P&gt;(param: P): P {\r\n  return param;\r\n}\r\n\r\n\/\/ ...and even arrow functions.\r\nconst genericArrowFunction = &lt;P,&gt;(param: P): P =&gt; param;<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=45&amp;ssc=57&amp;pln=1&amp;pc=1#code\/PTAEBkFMBcHIGdTwIYE9SoPYFdQDtJIATUaTUAdwCcBLaSUZUAM2zwGNobM9SALZNFLIA1pETI86GngAO2IbORVkAWxiQqoALAAoEIzwkqMbFTyI6AOlAB1OnxxCA5pAK128ADT8alxNB8DABG4kJYuOySoESYVnqsHFw8oDREblzQqACCUgAUSiqqAFyGqACUpZLoAN56oKAm0Ga8hWoA3HoAvnp6BgBCCqAAVBQOw6Cu7jSexQlsnNy8aRl0qAA8ACoAfAXKaqWblaCboHW6DU0toG2qnbo9un1gAGrIADZpc7rsPPCY70gVnemGceRWeEyG3g0FoeGcuwARDC4c5EeVyvdfhYAUCQWCIVD1nhsKpQlRdgAWABMGPuz1AADlMEIAG4fL56bH-QHA0Hg9KQtbrYKYXGSXYARkldN6+jAAE0cKAorxsPAGIFIKoWJgtDJ6FRmMh2OIrOa9AbNMbTaAAOJuTQzACSkOtJsgW0lPk21O2Z3qN32qklh0lcoat2ph2p3TlBnNVnY72Q8A18ETXJTaftjo8AGFs-B1gAFf3nSNUTCyUoliMqv6w7CcPUFKuyN7vbCQWvlAMXBq+DOydugAC8N3bne79waj0DrmgJfbeWOJf7g8apnMQ6sI+rs9Aj3n8tAicSiz+md0F+SvCmTvYADEFnfS7tbr3axut80d7d7hPBNzUkEhIFZNxGCoKsKBYV8lgzLlG0mPMZmyaDMAoF8kiWcdQFLLwP2DL9QHXMd-QAoA\" target=\"_blank\" rel=\"noreferrer noopener\">Try it on <\/a><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=45&amp;ssc=57&amp;pln=1&amp;pc=1#code\/PTAEBkFMBcHIGdTwIYE9SoPYFdQDtJIATUaTUAdwCcBLaSUZUAM2zwGNobM9SALZNFLIA1pETI86GngAO2IbORVkAWxiQqoALAAoEIzwkqMbFTyI6AOlAB1OnxxCA5pAK128ADT8alxNB8DABG4kJYuOySoESYVnqsHFw8oDREblzQqACCUgAUSiqqAFyGqACUpZLoAN56oKAm0Ga8hWoA3HoAvnp6BgBCCqAAVBQOw6Cu7jSexQlsnNy8aRl0qAA8ACoAfAXKaqWblaCboHW6DU0toG2qnbo9un1gAGrIADZpc7rsPPCY70gVnemGceRWeEyG3g0FoeGcuwARDC4c5EeVyvdfhYAUCQWCIVD1nhsKpQlRdgAWABMGPuz1AADlMEIAG4fL56bH-QHA0Hg9KQtbrYKYXGSXYARkldN6+jAAE0cKAorxsPAGIFIKoWJgtDJ6FRmMh2OIrOa9AbNMbTaAAOJuTQzACSkOtJsgW0lPk21O2Z3qN32qklh0lcoat2ph2p3TlBnNVnY72Q8A18ETXJTaftjo8AGFs-B1gAFf3nSNUTCyUoliMqv6w7CcPUFKuyN7vbCQWvlAMXBq+DOydugAC8N3bne79waj0DrmgJfbeWOJf7g8apnMQ6sI+rs9Aj3n8tAicSiz+md0F+SvCmTvYADEFnfS7tbr3axut80d7d7hPBNzUkEhIFZNxGCoKsKBYV8lgzLlG0mPMZmyaDMAoF8kiWcdQFLLwP2DL9QHXMd-QAoA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">the<\/a><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=45&amp;ssc=57&amp;pln=1&amp;pc=1#code\/PTAEBkFMBcHIGdTwIYE9SoPYFdQDtJIATUaTUAdwCcBLaSUZUAM2zwGNobM9SALZNFLIA1pETI86GngAO2IbORVkAWxiQqoALAAoEIzwkqMbFTyI6AOlAB1OnxxCA5pAK128ADT8alxNB8DABG4kJYuOySoESYVnqsHFw8oDREblzQqACCUgAUSiqqAFyGqACUpZLoAN56oKAm0Ga8hWoA3HoAvnp6BgBCCqAAVBQOw6Cu7jSexQlsnNy8aRl0qAA8ACoAfAXKaqWblaCboHW6DU0toG2qnbo9un1gAGrIADZpc7rsPPCY70gVnemGceRWeEyG3g0FoeGcuwARDC4c5EeVyvdfhYAUCQWCIVD1nhsKpQlRdgAWABMGPuz1AADlMEIAG4fL56bH-QHA0Hg9KQtbrYKYXGSXYARkldN6+jAAE0cKAorxsPAGIFIKoWJgtDJ6FRmMh2OIrOa9AbNMbTaAAOJuTQzACSkOtJsgW0lPk21O2Z3qN32qklh0lcoat2ph2p3TlBnNVnY72Q8A18ETXJTaftjo8AGFs-B1gAFf3nSNUTCyUoliMqv6w7CcPUFKuyN7vbCQWvlAMXBq+DOydugAC8N3bne79waj0DrmgJfbeWOJf7g8apnMQ6sI+rs9Aj3n8tAicSiz+md0F+SvCmTvYADEFnfS7tbr3axut80d7d7hPBNzUkEhIFZNxGCoKsKBYV8lgzLlG0mPMZmyaDMAoF8kiWcdQFLLwP2DL9QHXMd-QAoA\" target=\"_blank\" rel=\"noreferrer noopener\"> playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/generics.html\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">official docs<\/a> extensively talk about generics, so if you need a more lengthy introduction I recommend giving them a read. In this article, I\u2019ll just mention some interesting things about the topic.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For instance: generic types can be made optional by providing a default value in their declaration, just like with the input parameters of a function. If no type is specified when the component is used, TypeScript will fall back to the default one.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">\/\/ string is the default type for this interface.\r\ninterface GenericInterface&lt;T = string&gt; {\r\n  param: T\r\n}\r\n\r\n\/\/ Valid:\r\nconst value1: GenericInterface = {\r\n  param: \"string\"\r\n}\r\nconst value2: GenericInterface&lt;number&gt; = {\r\n  param: 42\r\n}\r\n\r\n\/\/ Not valid: TypeScript assumes param is typed as a string.\r\nconst value3: GenericInterface = {\r\n  param: 42\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=17&amp;ssc=2&amp;pln=1&amp;pc=1#code\/PTAEGcBcCcEsDsDmpblJAFgU1AEywGYCGArgDaToCeADjgQPbToaoryRbTEDGWAdAFgAUAk7cifUAHEs8LrB4BJDl15YAPABVQAXggwEiAHygA3iNCgaRaEQC2ALlBaRAXxEiQoAGpEysLiOIjwM8FCgAG7+JFgAjM6y8nDKqhJS+hbCVjZ2TqAARFBwSAXuIWER0WSxAEyJcgqp4uoa8CT2AEZcppmW1rYOzgAsteXCXmAAcgyU1YHOWrRYAMo8cDSURODgHVhouQ4oaJDLuKDbFwYliELCoeFzMVgAzA3Jiiotkjh92QN5EZjYRuIA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This feature can be used to introduce generic types into a component that currently has none, or to add more of them next to existing ones, while also keeping said component backward compatible.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Be careful though: setting a default type doesn\u2019t mean constraining the types that can be actually provided upon using the component. The type the user developer provides may be completely different from the default one, as you saw earlier with <strong>number<\/strong> and <strong>string<\/strong>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">That\u2019s why it\u2019d be a mistake to write something like this.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">\/\/ An interface of the project.\r\ninterface SomeInterface {\r\n  id: number\r\n  \r\n  name: string\r\n}\r\n\r\n\/\/ This function has a generic type, with the interface as its default.\r\nfunction someFunction&lt;T = SomeInterface&gt;(param: T): void {\r\n  \/\/ Not valid: there's no way to be sure T and SomeInterface will be compatible.\r\n  console.log(param.name);\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?#code\/PTAEFUDsHIEtIC4FMBOAzAhgYy7DoATJAG2P0gHsBnBFfDABweNiwwC9YLIkA6AWABQ8ZOmxJQAZQoBbJAElEqTFgkBvIaFCwCALlCQArjIBGqTaAuQMc-TRTwA5kIC+QoSFAAxQ5E7cJLAALCUMqfF9QBFgGClBHJB4HLAoAGlAUyFBiOCUxHDwM2QkiTENiBAFBNF8saO5QKmKfSDquSAAeABVQAF4pYsVRFSQAPgAKBgw6GX0ugEp9ADcKHVANQS1PADkGpYwWAgp9SiysaAAL+OmMP0LgiR6JaTkh5XFGm8hKIpkp6JMsBYVS0mSaxD4xAojkmNxkvGscnmAG5XEA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">However, it actually is possible to set a constraint for the types your component will be able to receive. You can do that with the <strong>extends<\/strong> keyword, which may also be used along with a default type.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">\/\/ An interface of the project.\r\ninterface SomeInterface {\r\n  id: number\r\n  \r\n  name: string\r\n}\r\n\r\n\/\/ This function has a generic type that extends SomeInterface.\r\nfunction someFunction&lt;T extends SomeInterface = SomeInterface&gt;(\r\n  param: T\r\n): void {\r\n  \/\/ Valid: whatever the actual type of T is,\r\n  \/\/ it will be compatible with SomeInterface.\r\n  console.log(param.name);\r\n}\r\n\r\n\/\/ Not valid: number is not compatible with SomeInterface.\r\nsomeFunction&lt;number&gt;(42);<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=18&amp;ssc=26&amp;pln=1&amp;pc=1#code\/PTAEEEDtQS0gXApgJwGYEMDGjQHtWjwAWOADsrgFaKbwB0AsAFBxJpY4DKuAtogJIIUGbKADezULAAmALlCQArjwBGKSaA2R0feQGd4yOAHNmAX2bMQoACpEYe0KkWRaMXNCLpH6UMcSQKDCYhACepDjE6PCgiAAeSJDSjtx8gmwiiIxMzq7w7tB6vIgAYi5uHgA8NrEJAcmgqQJC7KIAvI3F6cIcAHwAFBqk6Mg68jbMAJTyAG64MNLiGtYAaugANgvyAO5eSDMohCSgWPCKG2EReAQ1DgA0y2AwMdsw6+ugaqCYvMP5KuscK9iJ00i1MtkpD9IEVAXR1rhjP1hqMeHRtHxJgBucyWJjWAByuBiMw2WwUyjUyFgjkgxO+v2iMABQOeRFBzQyHGyRT4ZTyBUqSlUKAGABYAEzYoA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For complex cases, you can also use conditions to change the static typing for other parts of your components according to the provided types. A classic example: let\u2019s say you have a component that deals with a value, and this value could either be a single item or a list of items with the same type.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With generics, you\u2019re able to handle everything with just one interface like this:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>create an interface with two generic types, the type of the item <strong>T<\/strong> and a (constrained) boolean type <strong>Multiple<\/strong>;<\/li>\r\n\r\n\r\n\r\n<li>define the <strong>value<\/strong> property and the <strong>onChange<\/strong> callback, called whenever the value changes;<\/li>\r\n\r\n\r\n\r\n<li>set a condition for the type of the properties so it changes according to the type provided for <strong>Multiple<\/strong> by using <strong>extends<\/strong>.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Here\u2019s the result.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code\">\/\/ Multiple constrained on a boolean type, non-multiple as a default.\r\ninterface ComponentProps&lt;T, Multiple extends boolean = false&gt; {\r\n  \/\/ The value is a single item or an array.\r\n  value: Multiple extends false ? T : T[]\r\n\r\n  \/\/ onChange gets a single item or an array as an input parameter.\r\n  onChange: (newValue: Multiple extends false ? T : T[]) =&gt; void\r\n}\r\n\r\n\/\/ Object for the non-multiple case (using the default for Multiple):\r\nconst singleValueComponentProps: ComponentProps&lt;string&gt; = {\r\n  value: \"I'm just one string!\",\r\n\r\n  onChange: (newValue) =&gt; {\r\n    console.log(\r\n      \"This will always print TRUE:\", \r\n      typeof newValue === \"string\"\r\n    );\r\n  },\r\n};\r\n\r\n\/\/ Object for the multiple case:\r\nconst multipleValueComponentProps: ComponentProps&lt;string, true&gt; = {\r\n  value: [\"I'm\", \"an\", \"array\", \"of\", \"strings\", \"now!\"],\r\n\r\n  onChange: (newValue) =&gt; {\r\n    console.log(\r\n      \"Safely using the array methods, since newValue is an array:\"\r\n    );\r\n\r\n    newValue.forEach((currentValue) =&gt; console.log(currentValue));\r\n  },\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=33&amp;ssc=2&amp;pln=1&amp;pc=1#code\/PTAEFkFcBsBcEsAO0CmoDGB7AdgZ1gE4CG82KAJqDqEaAEaaapHaiwCeiKANKNjgFoAtjATI0RXDVDkUAMyKiAdAFgAUKVgoCC9GgDCmIYhwpssAAoFMiXAB4AKryhwkqUCgAeW7OSkMmFBZQAF5QBWhcFAA+UABvdVBQEFAHAAs0ADciaEg0eClaXFIAc3d4LSEqAhpWIgJidlU1JOzclAAuCFE3NC8fP3CcqNAAflTQLocAbQBddUTksBx9NJYStA3YQtBi7DL8yuramgaidhpC1lJESFhQRHqiIRQtAmaklbX9ztAACjIAHcAGo5PJdFxidz9MyDCIjcYOSapOYASlCsUymHg5HUAF8FmoUgB5OgAKxQ6HuckwNVgGT4ghErnEGEkaD+kD2JTYDNkClE4Vp3RZqFRHXUWDw925qFB7UMxlM5isNlwXUVJjIKustjs+AIpViYQSLVAbXBoAARABJADkVTJXPupl2hFKAEIrdxCZ9sKt1r8ASgQWCUOiQrFTUkklLcIElNBMCU-osY9b0gVQID4NBoDRoIDzlJEIbzKkAEoAVQAoh1vaA0zGOFxMHI+CH5XlQiEwlaDaUrU3UQBuRZ4n1qPFjtTqEnkynU4X0tDMqFodDsiVqOP3Ne9LsoTXKyy69WgY-a09q-Xu-a8Qh5Y3xRYW37TW0OhtWljf+qNb822-Ad9lwb9+EBL1ZknRYvkDLpg1DdoIyjJs4wTJMUybJIrQAZSIOQUGgC4uVKXkJDOC4XnpTA-F4PY9A7JDuyzYJ-3OethxnJsgUPJQaQIGsiHQNI-j+dBIAaMxYEPFCMBweNUETZNxMkghpNk0dx0nPEgA\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Type narrowing: type predicates<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">After mentioning it in the <a href=\"https:\/\/www.oimmei.com\/en\/typescript-5-tricks-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">first article<\/a>, let\u2019s talk some more about <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/narrowing.html\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">type narrowing<\/a>. And today, let\u2019s try and give this extremely important feature the respect it deserves.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">First off, a recap of what I said last time while discussing <a href=\"https:\/\/www.oimmei.com\/en\/typescript-5-tricks-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">discriminated unions<\/a>: type narrowing is basically the mechanism that allows TypeScript to infer what type a variable will be at runtime in a specific part of the code, using the static typing you defined and the flow of your program, so the transpiler can present the appropriate errors to you while turning your code into JavaScript. That\u2019s all fine and good, but what I did <em>not<\/em> emphasize last time is how freaking powerful and ubiquitous type narrowing is in TypeScript, and how often we all take advantage of it without even realizing.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Think about a function with a parameter that can either be a string or a number. If it\u2019s a string, you want to display its length; if it\u2019s a number, you want to <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Number\/toFixed\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">display it with fixed-point notation<\/a>. Most JavaScript developers will naturally end up writing something like this, using the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/typeof\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">typeof<\/a> operator.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code\">function someFunction (value: string | number): void {\r\n  if (typeof value === \"string\") {\r\n    \/\/ Printing the length:\r\n    console.log(\"Length of the string:\", value.length);\r\n  } else {\r\n    \/\/ Printing the value:\r\n    console.log(\"Value:\", value.toFixed());\r\n  }\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=9&amp;ssc=2&amp;pln=1&amp;pc=1#code\/GYVwdgxgLglg9mABAZzgWwKYDFzXkgCgDcBDAGxAwC4UoAnGMAc0QB9EwQ0AjDOgShpE4MACaIA3gChEiGMEQEoATwAOGOAtIUMiALwHEAImT1GTI-0kzZiAPR3EABQZhYzRFAAWushmbeVDayEAiofgB0ZHBMBEYAMv5M3oianj60rkxURgA0iNqUUUne-ADcNgC+iBhkyLrStvaOLozuLN66hdTBiKFg4RhRMXEAauSUOfndEVBwWDAAHhiiBPzlVVKVQA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">That\u2019s simple, right? Nevertheless, a number of non-trivial things are happening beneath the surface.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">In the function signature, <strong>value<\/strong> is typed as being either a number or a string, thanks to a lovely <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/everyday-types.html#union-types\">union type<\/a>. In the branches of the <em>if<\/em> construct, though, the code takes advantage of features that aren\u2019t common to these two types: in the <em>then<\/em> branch it uses <strong>length<\/strong>, which doesn\u2019t exist for <strong>number<\/strong>; in the <em>else<\/em> branch it uses <strong>toFixed<\/strong>, which doesn\u2019t exist for <strong>string<\/strong>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">If you try and remove the <em>if<\/em>, both of its former branches understandably throw an error.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">function someFunction (value: string | number): void {\r\n  \/\/ Printing the length:\r\n  console.log(\"Length of the string:\", value.length);\r\n  \/\/ Printing the value:\r\n  console.log(\"Value:\", value.toFixed());\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=6&amp;ssc=2&amp;pln=1&amp;pc=1#code\/GYVwdgxgLglg9mABAZzgWwKYDFzXkgCgDcBDAGxAwC4UoAnGMAc0QB9EwQ0AjDOgShpE4MACaIA3gChEiAPRzEABQZhYzRFAAWGRGQzNtVGYggJU+gHRk4TAgCIAMgabbEcYJp21VTKvYAaRFIKDGsXbX4AbhMFZVV1Fm1dEMpjWTMwCzCbO3sANXI0wOCisKg4LBgADwxRAn5oqQBfIA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">And yet, TypeScript doesn\u2019t have any issue in the first version of the snippet. What\u2019s happening here?<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The answer is type narrowing. TypeScript analyzes the flow of your code, and infers that, while executing a specific line, the type of a value will be more restrictive than the one you explicitly declared.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The <strong>typeof<\/strong> operator, for instance, is one of the so-called <em>type guards<\/em>, meaning special checks which have an effect on the typing deduced by TypeScript for a given value. That\u2019s why the first version of the snippet works: starting from the union type <strong>string | number<\/strong>, TypeScript looks at the <em>if<\/em> condition and realizes that <strong>value<\/strong> will be a <strong>string<\/strong> for the duration of the <em>then<\/em> branch and, by exclusion, it will be a <strong>number<\/strong> in the <em>else<\/em> branch.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Type narrowing is a crucial feature in TypeScript projects, and it applies to a lot of different operators and constructs: typeof operators, comparisons, assignments, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/in\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">in<\/a> operators, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/instanceof\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">instanceof<\/a> operators, <em>if<\/em> constructs, <em>switch<\/em> constructs\u2026<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">But you\u2019re not looking for lengthy explanations about the inner workings of TypeScript. You\u2019re here to find some tips you can use in your code and tell other people at parties in order to win respect and admiration from your friends, and I won\u2019t let you down.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">(Warning: knowing the following information may not actually lead to winning respect and admiration from your friends. The author of this article declines every responsibility for your poor social skills.)<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Sometimes, taking advantage of type narrowing may be harder than usual. Sure, as long as we\u2019re talking about <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Data_structures#primitive_values\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">primitive types<\/a> such as strings or numbers, or built-in utilities such as <strong>Date<\/strong>, things are easy and straightforward, but\u2026 what about user-defined interfaces?<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">TypeScript interfaces, as useful as they are, have a pretty big downside: they don\u2019t exist at runtime. Actually, they don\u2019t exist at all, since JavaScript has no such construct at the time of writing. They\u2019re only meant to help developers catch static type errors, but they don\u2019t survive transpilation in any form. So no, One does not simply\u2122 use <strong>instanceof<\/strong> with TypeScript interfaces; narrowing takes a bit of extra effort for those.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A pretty standard situation: you have an interface <strong>SomeInterface<\/strong>, a second interface <strong>SomeExtension<\/strong> which extends the former, and a function that receives a <strong>SomeInterface<\/strong> object as an input. Since inheritance is in place, the input parameter may be a <strong>SomeExtension<\/strong> object; let\u2019s say you want to perform some additional operation if that happens. You may try and use the <strong>in<\/strong> operator to check for an extension property, but sadly it won\u2019t be enough.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">interface SomeInterface {\r\n  id: number\r\n\r\n  title: string\r\n}\r\n\r\ninterface SomeExtension extends SomeInterface {\r\n  description: string\r\n\r\n  content: string\r\n\r\n  otherFields: Record&lt;string, any&gt;\r\n}\r\n\r\nfunction someFunction (obj: SomeInterface): void {\r\n  \/\/ Printing every property to the console.\r\n  \/\/ Valid:\r\n  console.log(obj.id);\r\n  console.log(obj.title);\r\n\r\n  if (\"description\" in obj) {\r\n    \/\/ The in operator let us use description...\r\n    console.log(obj.description);\r\n\r\n    \/\/ ...but it's not enough to convince \r\n    \/\/ TypeScript that obj has type SomeExtension.\r\n    console.log(obj.content);\r\n    console.log(obj.otherFields);\r\n  }\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=30&amp;ssc=2&amp;pln=1&amp;pc=1#code\/JYOwLgpgTgZghgYwgAgMoHsC2ECS5rxLIDeAUMssACYBcyIArpgEbSnnJjBgA2EdAZzBRQAc1IBfdqEixEKDNgCiAD0ggBwdCGQQ1EEFQFosufHKJkKVCAIQiADl22DhY9hQTb1YVyJDiHOhgABbQAGLAEDxGdABKEF5QVAA8Qv6iADTIcCAAngB8kuwwDCAIzjoCpuFlFVo6ABTozABWdIpmsoQQAJR0AG7o1CQcAPRjyAAK-lwBugPQecgOUOgO0GDLYOicYcheGuh8AHTjkwBqcDzUNByH1ac86KLNbSfUvQDc99qPECdnq8Wq0TlxeH0fhxgDBkI0AEQ2OyOSrwyg6EG9UYUCgTZAAFX2oGQ62gcB2UGQfDAyAYxjpKCR9mATgaJ3ZHE8f2OAKBb1BTJRDW+HhxePZJ2YDBp3AA5MYQMFdIqGKIQpxdocBqAiJzkHj8XkNqhmU49uSSW1kCE4MYthsTMp9Bo2XqHjzAS9+SdDj4RTiDtynl6QSdgmEoJFokZ-cgpBIgA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">(Up to TypeScript 4.8, even accessing <strong>description<\/strong> this way would have resulted in an error. Starting from version 4.9, type narrowing was slightly reworked, meaning you can access the property you explicitly check with <strong>in<\/strong>, even though the inferred type for it will be <strong>unknown<\/strong>.)<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">What you need to do here is make TypeScript understand that you\u2019re rightfully accessing the extension properties, or, in other words, that you\u2019re using those properties only when <strong>obj<\/strong> actually has type <strong>SomeExtension<\/strong>. Fortunately, this can be done with <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/narrowing.html#using-type-predicates\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">type predicates<\/a>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Type predicates let you define custom type guards, based upon arbitrarily complex conditions, which assert that a specific variable will be the given type in a specific code block &#8211; just like with <strong>typeof<\/strong>, but the logic is entirely defined by the developer.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">So, here\u2019s how you can solve the extension problem: create a function (<strong>isSomeExtension<\/strong>) that receives a <strong>SomeInterface<\/strong> object, and returns a type predicate asserting the input parameter is a <strong>SomeExtension<\/strong> object. The function body has to examine the input parameter to establish if the predicate is correct &#8211; or, as someone could say, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Duck_typing\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">if the parameter walks and quacks<\/a> &#8211; and return <strong>true<\/strong> if it is, and <strong>false<\/strong> if it isn\u2019t.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Finally, use that function inside the <em>if<\/em> condition for <strong>someFunction<\/strong>.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code\">interface SomeInterface {\r\n  id: number\r\n\r\n  title: string\r\n}\r\n\r\ninterface SomeExtension extends SomeInterface {\r\n  description: string\r\n\r\n  content: string\r\n\r\n  otherFields: Record&lt;string, any&gt;\r\n}\r\n\r\nfunction isSomeExtension (value: SomeInterface): value is SomeExtension {\r\n  \/\/ If value contains description, it's a SomeExtension object.\r\n  return \"description\" in value;\r\n}\r\n\r\nfunction someFunction (obj: SomeInterface): void {\r\n  \/\/ Printing every property to the console.\r\n  \/\/ Valid:\r\n  console.log(obj.id);\r\n  console.log(obj.title);\r\n\r\n  if (isSomeExtension(obj)) {\r\n    \/\/ Valid: TypeScript acknowledges obj is a \r\n    \/\/ SomeExtension object in this part of the code.\r\n    console.log(obj.description);\r\n    console.log(obj.content);\r\n    console.log(obj.otherFields);\r\n  }\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=33&amp;ssc=2&amp;pln=1&amp;pc=1#code\/JYOwLgpgTgZghgYwgAgMoHsC2ECS5rxLIDeAUMssACYBcyIArpgEbSnnJjBgA2EdAZzBRQAc1IBfdqEixEKDNgCiAD0ggBwdCGQQ1EEFQFosufHKJkKVCAIQiADl22DhY9hQTb1YVyJDiHOhgABbQAGLAEDxGdABKEF5QVAA8Qv6iADTIcCAAngB8kuwwDCAIzjrAAooQquqa2sgAFABucDwM-CbYeLKEEACUdO2dKNU9dfoaWjpWyAD0C8g4MMijXche4HCgxjZ2jpXZ3ADkxnCT9QaNOujMAFaJYAB0HFAQYAxQOgBEB-ZgE5Zr9KDoNhAANzFUilcqVZACUzhMoVWYte4POi1PoEeTDdboagkDhLZAABX8XACula0DyyAcUHQDmgYAZYHQnDCW20SL4bwoZIAah1qDQONt+RAXjx0KJmpiXtRBtDPHz0AK5QqlVxeENoRxgGtmtVatcZtpFY9BoMSRQhctRTxxcgACp5VmoQFOHIIADWIHQAHc+FRRLZkJjKBdkBxHVdprco49nmDuRMHHAoGAo2tQigvDZBQ6pZqZdrrQ8XgCjrNVfHeRpy7L5VWXtsfA2HU3pa2dY8XsEwlBItEjN3kFIJEA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Yay!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">An important note to close this long paragraph: keep in mind that type predicates let you pretty much \u201cskip\u201d the built-in type checking system. When a type predicate is in place, TypeScript will entirely trust your own type guard. That means you have to be extra careful while writing the function body: if something\u2019s wrong in there, you won\u2019t realize it until you notice a bug at runtime.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Function overloading<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">If you\u2019re used to programming languages like Java, you should be familiar with <a href=\"https:\/\/www.w3schools.com\/java\/java_methods_overloading.asp\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">method overloading<\/a>. It\u2019s a feature that allows you to create different methods with the same name and a different parameter list inside a class or an interface. That way, you\u2019ll be able to use every different method according to the input parameters.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Did you know that a very similar &#8211; and useful! &#8211; feature exists in TypeScript? That feature is <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/functions.html#function-overloads\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">function overloading<\/a>, and it can be used both on base functions and in class methods.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">It works pretty much the same as method overloading, but with one key difference: while method overloading allows you to actually create multiple methods with different bodies, function overloading requires you to create just one function, and allows you to associate multiple signatures to it. This means you\u2019ll have to write the function itself so that it\u2019s compatible with every possible signature in order to avoid a type error.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code\">\/\/ Multiple signatures:\r\nfunction someFunction (param: number): number;\r\nfunction someFunction (param: string): string;\r\n\r\n\/\/ Implementation of the function:\r\nfunction someFunction (\r\n  param: number | string\r\n): number | string {\r\n  if (typeof param === \"number\") {\r\n    console.log(\"It's a number!\");\r\n  } else {\r\n    console.log(\"It's a string!\");\r\n  }\r\n\r\n  return param;\r\n}\r\n\r\nconst val1 = someFunction(42);\r\nconst val2 = someFunction(\r\n  \"So long, and thanks for all the fish\"\r\n);\r\n<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=22&amp;ssc=1&amp;pln=1&amp;pc=1#code\/PTAEFkFcBsBcEsAO0CmoDO8DmA7AhrJAE4roBcAUAGaQ4DGCA9jhowLYoBitD8zoACkR4ieNmVA5IbAEYoiASglTZ8gNzUeTFunZctfFkJFiJ6WEXg4sSjBatYNFEKACSbZCg45YBQ6EYqUFgACzQaem1KCN5+XQ5uSP8BClBQYVFxSWk5IlAAHztLawpbFVyCoodQAG9U0HgggVgAT0QUQPSTNlAAXn7QACJy+UGFWvq0umZdVAA6aEYsAUHXWABydFA8bNUiAEIxjTSAX1AUaHQ0OrSpmcZ5xeXVja2d82KsQ4Vj0BOKeokQhEFgZMQaf4UaY4cygABueGgAEY+qwEgZmAIACwAJh+UJmsHhiJxqPi+iSmPqgwAyoxQItrAAabY4AAmwRCeBwAGstlRGHlEdBOeF4OgQoNShogA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Having to define only one function body for every signature may seem very limiting, but keep in mind: by declaring your function like this, TypeScript will be able to correctly infer the output type according to the input parameters type. In other words, you won\u2019t have to manually type narrow the result returned by your function.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">To demonstrate how helpful this can be, let\u2019s add a few lines to the previous snippet.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code\">\/\/ Multiple signatures:\r\nfunction someFunction (param: number): number;\r\nfunction someFunction (param: string): string;\r\n\r\n\/\/ Implementation of the function:\r\nfunction someFunction (\r\n  param: number | string\r\n): number | string {\r\n  if (typeof param === \"number\") {\r\n    console.log(\"It's a number!\");\r\n  } else {\r\n    console.log(\"It's a string!\");\r\n  }\r\n\r\n  return param;\r\n}\r\n\r\nconst val1 = someFunction(42);\r\nconst val2 = someFunction(\r\n  \"So long, and thanks for all the fish\"\r\n);\r\n\r\n\/\/ Valid:\r\nconsole.log(val1.toFixed());\r\nconsole.log(val2.length);<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=25&amp;ssc=26&amp;pln=1&amp;pc=1#code\/PTAEFkFcBsBcEsAO0CmoDO8DmA7AhrJAE4roBcAUAGaQ4DGCA9jhowLYoBitD8zoACkR4ieNmVA5IbAEYoiASglTZ8gNzUeTFunZctfFkJFiJ6WEXg4sSjBatYNFEKACSbZCg45YBQ6EYqUFgACzQaem1KCN5+XQ5uSP8BClBQYVFxSWk5IlAAHztLawpbFVyCoodQAG9U0HgggVgAT0QUQPSTNlAAXn7QACJy+UGFWvq0umZdVAA6aEYsAUHXWABydFA8bNUiAEIxjTSAX1AUaHQ0OrSpmcZ5xeXVja2d82KsQ4Vj0BOKeokQhEFgZMQaf4UaY4cygABueGgAEY+qwEgZmAIACwAJh+UJmsHhiJxqPi+iSmPqgwAyoxQItrAAabY4AAmwRCeBwAGstlRGHlEdBOeF4OgQoNSk4XAA1RHwNmUaGzFALJYCBHIuawRiceAADxQbIECnxKoeaqempJCxQ1lCPyAA\" target=\"_blank\" rel=\"noreferrer noopener\">Try it on <\/a><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=25&amp;ssc=26&amp;pln=1&amp;pc=1#code\/PTAEFkFcBsBcEsAO0CmoDO8DmA7AhrJAE4roBcAUAGaQ4DGCA9jhowLYoBitD8zoACkR4ieNmVA5IbAEYoiASglTZ8gNzUeTFunZctfFkJFiJ6WEXg4sSjBatYNFEKACSbZCg45YBQ6EYqUFgACzQaem1KCN5+XQ5uSP8BClBQYVFxSWk5IlAAHztLawpbFVyCoodQAG9U0HgggVgAT0QUQPSTNlAAXn7QACJy+UGFWvq0umZdVAA6aEYsAUHXWABydFA8bNUiAEIxjTSAX1AUaHQ0OrSpmcZ5xeXVja2d82KsQ4Vj0BOKeokQhEFgZMQaf4UaY4cygABueGgAEY+qwEgZmAIACwAJh+UJmsHhiJxqPi+iSmPqgwAyoxQItrAAabY4AAmwRCeBwAGstlRGHlEdBOeF4OgQoNSk4XAA1RHwNmUaGzFALJYCBHIuawRiceAADxQbIECnxKoeaqempJCxQ1lCPyAA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">the<\/a><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=25&amp;ssc=26&amp;pln=1&amp;pc=1#code\/PTAEFkFcBsBcEsAO0CmoDO8DmA7AhrJAE4roBcAUAGaQ4DGCA9jhowLYoBitD8zoACkR4ieNmVA5IbAEYoiASglTZ8gNzUeTFunZctfFkJFiJ6WEXg4sSjBatYNFEKACSbZCg45YBQ6EYqUFgACzQaem1KCN5+XQ5uSP8BClBQYVFxSWk5IlAAHztLawpbFVyCoodQAG9U0HgggVgAT0QUQPSTNlAAXn7QACJy+UGFWvq0umZdVAA6aEYsAUHXWABydFA8bNUiAEIxjTSAX1AUaHQ0OrSpmcZ5xeXVja2d82KsQ4Vj0BOKeokQhEFgZMQaf4UaY4cygABueGgAEY+qwEgZmAIACwAJh+UJmsHhiJxqPi+iSmPqgwAyoxQItrAAabY4AAmwRCeBwAGstlRGHlEdBOeF4OgQoNSk4XAA1RHwNmUaGzFALJYCBHIuawRiceAADxQbIECnxKoeaqempJCxQ1lCPyAA\" target=\"_blank\" rel=\"noreferrer noopener\"> playground <\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">In the example above, <strong>val1<\/strong> and <strong>val2<\/strong> are used as a number and as a string respectively. You\u2019re able to do this without any error specifically because of function overloading: TypeScript can tell that <strong>someFunction<\/strong> will return a number when it receives a number and a string when it receives a string.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Just for comparison, here\u2019s how things would have changed <em>without<\/em> using function overloading.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code highlighted-error\">function someFunction (\r\n  param: number | string\r\n): number | string {\r\n  if (typeof param === \"number\") {\r\n    console.log(\"It's a number!\");\r\n  } else {\r\n    console.log(\"It's a string!\");\r\n  }\r\n\r\n  return param;\r\n}\r\n\r\nconst val1 = someFunction(42);\r\nconst val2 = someFunction(\r\n  \"So long, and thanks for all the fish\"\r\n);\r\n\r\n\/\/ Not valid: TypeScript is unable\r\n\/\/ to infer the output type.\r\nconsole.log(val1.toFixed());\r\nconsole.log(val2.length);\r\n\r\n\/\/ We have to manually type\r\n\/\/ narrow the variables:\r\nif (typeof val1 === \"number\") {\r\n  console.log(val1.toFixed);\r\n}\r\nif (typeof val2 === \"string\") {\r\n  console.log(val2.length);\r\n}<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=30&amp;ssc=2&amp;pln=1&amp;pc=1#code\/GYVwdgxgLglg9mABAZzgWwKYDFzXkgCgChFEAHAQwCcK0AuRMENAIwysQB8UoqYwA5kQCUDJq3ZcefQYgDeJRDGCICUAJ5kMcFZRppEAXmOIAROLZVTw+YtIQEqADYYAdE7gCCpgJJQA5MiIFIzMlgCE1gDcigC+iBhOyBi2pPaOcC7unt5+gcHS-AKRwjGksUSKVBhQIFRIerQxFUQOYMhQiABuFE4AjEYo6Ni4sAgEACwATKWtjp09TlODqJg4kGNgxKSmAMpwiB6CADTBYAAmiFAAFhRgANZBwHAcvU5X1ynAMMjXpiIxIgAeiBiAAcnAFr0YOcGAAVTQYXYQPhkTo-RDgCgsFzA0FQA78YCSG4pOAgKBkClXRGuObtTJuDxeRZ9VwErAwAAeGHOBGEszaziZOUWU3cGEEN1meMQAHUUrcuikCYg0HcQG91DStLKwNQqHAAO4fFI9PjYlzIOhEZSqDRaHTdXoDYyGMwWdjWVKIIWM7Isl3suCcnnnWYVO1qRFOsVGEymDoyATehTpBlZZkEMUSqXXCNAA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With even this simple snippet becoming a lot more verbose than before, you can imagine the impact this feature could have on a complex project.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">There are several situations where function overloading can be useful. For instance, you can use it when you have a function that accepts either a single value or an array of values as a parameter.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-syntaxhighlighter-code\">function multiplyValue(\r\n  value: number, \r\n  multiplyBy: number,\r\n): number;\r\nfunction multiplyValue(\r\n  value: number[], \r\n  multiplyBy: number,\r\n): number[];\r\n\r\n\/\/ Multiplies a single value of an array of values \r\n\/\/ by the second parameter and returns the result.\r\nfunction multiplyValue(\r\n  value: number | number[], \r\n  multiplyBy: number,\r\n): number | number[] {\r\n  if (Array.isArray(value)) {\r\n    const result = [];\r\n\r\n    for (let i = 0; i &lt; value.length; i++) {\r\n      result.push(value[i] * multiplyBy);\r\n    }\r\n\r\n    return result;\r\n  } else {\r\n    return value * multiplyBy;\r\n  }\r\n}\r\n\r\nconst singleValue = multiplyValue(11, 2);\r\nconst arrayOfValues = multiplyValue(\r\n  [1, 1, 2, 3, 5],\r\n   5\r\n);\r\n\r\n\/\/ singleValue is a number:\r\nconsole.log(singleValue.toFixed());\r\n\r\n\/\/ arrayOfValues is an array of numbers:\r\narrayOfValues.forEach((item) =&gt; {\r\n  console.log(item.toFixed())\r\n});<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.typescriptlang.org\/play?ssl=41&amp;ssc=4&amp;pln=1&amp;pc=1#code\/GYVwdgxgLglg9mABAWxAG1gBzQTwGoCGaIApgBQBQiiAbkaQFyJgjIBGJATgDSJUrosuAEI4mLdl24UAlONYdOAbgqhIsBAIwxs+euX51iJeZM4BtALq9+qbbtGnF0ucwVcrKigHpviALKCOmgwJADOiASIYTBgAOZoJLT6iHDAkUgEnJwEOKnpRqQRPn5seVAAFklhJBAIACaImFkEyCRQXBmNnO0gnGARlUk9YYIAdKrg0PBIdkJ6xpTUhSZuZogAPmuKVjbUc8E4jttSsk6dWxI7logA3vww6WQAgtm5YzBhrzk4ZCsyMju-GodQGUEQI0EiAAvIhPBRgYhgHBOIgyIlwTAYYgAAxKRBYgA8yWMY0S8Uq+JgAGpqYD7tRGRDwuNMCAwhU-vpzDAbgAqLTzUQyFRMgC+CKZPSgfSQkIwosQYsQJDQNSBUt6-RJpEQAoODhwiolEoooLC4Ji8UShGM2INuFtpDIAEYXbwAEwis0IC2RN44ADywCd4XtQV0oaWcPdiFjHt4AGZeABWazAlOyLy+aKxBIkUMEiJRK5cBg+gZwRJkuBxMhW-OhsZQOAAMRgAA8SPUyADs34sj9g6GIp8Mv6fvkTpwwuXB7lh-owmNkZwAKIECCcsgwDrIQHQgB8GsQ5qrJBrdd3JGQzbbne7vZkFDFIqAA\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Try it on the playground<\/a><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">(Notice how <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/isArray\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Array.isArray<\/a> is a valid type guard, as well.)<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No type guard necessary outside of the function body! Isn\u2019t it lovely to be able to type less code?<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Closing words<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">That closes this second article about TypeScript (didn\u2019t read the first part yet? <a href=\"https:\/\/www.oimmei.com\/en\/typescript-5-tricks-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">What are you waiting for?!<\/a>). I hope I\u2019ve been able to make you discover something new, or perhaps to shine some light on a few mechanics many developers never really think about.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">If you have some secret TypeScript tools you\u2019d like to share, I can\u2019t wait to know about them. Will a third article ever be published? Who knows!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.oimmei.com\/en\/about-us\/\" target=\"_blank\" rel=\"noreferrer noopener\">Andrea Cioni.<\/a><\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>Are you a web developer? Did you happen to work on a fairly complex JavaScript project, such as a Node.js server or a nice and complicated React website? Have the limitations in the programming language ever caused you to lose a lot of time and sanity in order to track down particularly sneaky bugs? Well, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":25736,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[91],"tags":[],"class_list":["post-20607","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development-en"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"Discover advanced TypeScript tips and tools to build safer, more efficient, and easier-to-maintain web projects with strongly typed code\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Oimmei Team\"\/>\n\t<meta name=\"google-site-verification\" content=\"nrov3ZDmFh2g122GMXaTWPiPrzv3uAspJFs_42s7-6s\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.oimmei.com\/en\/typescript-more-5-tricks-for-development\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Oimmei Technologies | The Boutique Agency\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"TypeScript: 5 More Tricks for Development | Oimmei Technologies\" \/>\n\t\t<meta property=\"og:description\" content=\"Discover advanced TypeScript tips and tools to build safer, more efficient, and easier-to-maintain web projects with strongly typed code\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.oimmei.com\/en\/typescript-more-5-tricks-for-development\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/www.oimmei.com\/wp-content\/uploads\/2026\/08\/oimmei-cover-website-26-scaled.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/www.oimmei.com\/wp-content\/uploads\/2026\/08\/oimmei-cover-website-26-scaled.png\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2023-08-01T08:16:56+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2025-08-06T09:21:59+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"TypeScript: 5 More Tricks for Development | Oimmei Technologies\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Discover advanced TypeScript tips and tools to build safer, more efficient, and easier-to-maintain web projects with strongly typed code\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.oimmei.com\/wp-content\/uploads\/2026\/08\/oimmei-cover-website-26-x.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"TypeScript: 5 More Tricks for Development | Oimmei Technologies","description":"Discover advanced TypeScript tips and tools to build safer, more efficient, and easier-to-maintain web projects with strongly typed code","canonical_url":"https:\/\/www.oimmei.com\/en\/typescript-more-5-tricks-for-development\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"google-site-verification":"nrov3ZDmFh2g122GMXaTWPiPrzv3uAspJFs_42s7-6s","miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"Oimmei Technologies | The Boutique Agency","og:type":"article","og:title":"TypeScript: 5 More Tricks for Development | Oimmei Technologies","og:description":"Discover advanced TypeScript tips and tools to build safer, more efficient, and easier-to-maintain web projects with strongly typed code","og:url":"https:\/\/www.oimmei.com\/en\/typescript-more-5-tricks-for-development\/","og:image":"https:\/\/www.oimmei.com\/wp-content\/uploads\/2026\/08\/oimmei-cover-website-26-scaled.png","og:image:secure_url":"https:\/\/www.oimmei.com\/wp-content\/uploads\/2026\/08\/oimmei-cover-website-26-scaled.png","article:published_time":"2023-08-01T08:16:56+00:00","article:modified_time":"2025-08-06T09:21:59+00:00","twitter:card":"summary","twitter:title":"TypeScript: 5 More Tricks for Development | Oimmei Technologies","twitter:description":"Discover advanced TypeScript tips and tools to build safer, more efficient, and easier-to-maintain web projects with strongly typed code","twitter:image":"https:\/\/www.oimmei.com\/wp-content\/uploads\/2026\/08\/oimmei-cover-website-26-x.png"},"aioseo_meta_data":{"post_id":"20607","title":null,"description":"Discover advanced TypeScript tips and tools to build safer, more efficient, and easier-to-maintain web projects with strongly typed code","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"BlogPosting","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"titles":[],"descriptions":[],"socialPosts":{"email":[],"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2025-03-15 23:44:07","updated":"2025-08-06 09:22:53","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.oimmei.com\/en\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">|<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.oimmei.com\/en\/category\/software-development-en\/\" title=\"Software Development\">Software Development<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">|<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tTypeScript: 5 More Tricks for Development\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.oimmei.com\/en\/"},{"label":"Software Development","link":"https:\/\/www.oimmei.com\/en\/category\/software-development-en\/"},{"label":"TypeScript: 5 More Tricks for Development","link":"https:\/\/www.oimmei.com\/en\/typescript-more-5-tricks-for-development\/"}],"_links":{"self":[{"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/posts\/20607","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/comments?post=20607"}],"version-history":[{"count":0,"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/posts\/20607\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/media\/25736"}],"wp:attachment":[{"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/media?parent=20607"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/categories?post=20607"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.oimmei.com\/en\/wp-json\/wp\/v2\/tags?post=20607"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}