DEV Community

Cover image for Solving TypeScript Errors - TotalTypeScript Challenges
Alvison Hunter Arnuero | Front-End Web Developer
Alvison Hunter Arnuero | Front-End Web Developer

Posted on • Updated on

Solving TypeScript Errors - TotalTypeScript Challenges

Howdy, folks:

Are you venturing into the realm of TypeScript? Whether you're a novice seeking guidance, an intermediate looking to level up, or someone wanting to brush up on TypeScript, you're in good company! Come along on this journey as we navigate together through the intricacies of TypeScript. Our focus this time will be on exploring examples of common TypeScript errors and unraveling their potential solutions. Let's embark on this insightful expedition hand in hand.

Solving TypeScript Errors

TypeScript, fondly abbreviated as TS, acts as the vigilant custodian of code, employing a rich array of tools such as interfaces, inference types, generics, union types, narrowing types, and discriminated unions. To the uninitiated, this plethora of technical terms may initially appear as an indecipherable maze of jargon.

Ah, the captivating journey into TypeScript, a realm both exhilarating and perplexing, particularly for the budding learner. While its type checking capabilities offer immense benefits, they often accompany intricate error messages that demand meticulous deciphering and resolution. Many of us approach it tentatively at first, apprehensive of its complexities, only to discover its indispensable practicality. Personally, I view it as a life-saving tool, a steadfast ally in programming endeavors, without a shadow of doubt.

But wait, weren't we aiming to delve into TypeScript Errors and explore potential solutions? Ok, you are right, sorry, I got carried away. let's refocus. You might be pondering how to initiate this discussion and what resources are available for us to navigate through this topic. Fear not, young Padawan, for totaltypescript.comstands ready with great challenges and tutorials on this matter. Whether you're grasping the basics or delving deeper, this website's tutorials will illuminate your way through TypeScript's most puzzling errors.

Curious why I'm endorsing totaltypescript.com? Well, If you're thinking I might be on their payroll, let me dispel that notion: I'm not. However, delving into their tutorials has fine-tuned my ability to adeptly decipher error messages. Reason to that, I highly recommend you to explore this tutorial for insights on TypeScript errors like Type Not Assignable, Property Not Found, and Possibly Null or Undefined. This tutorial offers pragmatic solutions to some of the most common TypeScript errors. Moreover, mister Matt Pocock is an amazing of TypeScript Guru, a true luminary warrior in the realm of the TypeScript Kingdom!

As to the TS Errors Solutions, The interactive tutorial on totaltypescript.com acts as your hands-on expedition to sharpen TypeScript prowess. Dive into each problem, absorb nuances, consult documentation, and explore type definitions. Experiment with varied solutions, embracing different approaches while experimenting with each problem.

Remember, a solid grasp of TypeScript fundamentals is crucial for this immersive journey. Get ready to unravel mysteries and elevate your TypeScript proficiency through engaging challenges!

Discover the exercises and my solutions below. Feel free to attempt your own solutions and share them in the comments. Together, let's elevate our TypeScript expertise as we learn and progress collectively!

Solving TypeScript Errors Challenges Information

Page: TotalTypeScript.com
Github Repo: Solving TypeScript Errors


Fixing "X Is Not Assignable To Y"

Welcome to this TypeScript exploration! We're diving into a user object and a UserProfile interface in TypeScript. Our mission? To hunt down three potential solutions for a tricky type error. Your task is to unearth the underlying cause behind TypeScript's rejection of the 'blue' value. Let's delve into why this hiccup occurs and brainstorm some promising fixes.

Error Message: Type 'blue' is not assignable to type 'light' or 'dark'.

interface UserProfile {
    id: string;

    preferences: {
        theme: "light" | "dark";
    };
}

let user: UserProfile = {
    id: "123",
    preferences: {
        theme: "blue",
    },
};
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

interface UserProfile {
    id: string;

    preferences: {
-        theme: "light" | "dark";
+        theme: string;
    };
}

let user: UserProfile = {
    id: "123",
    preferences: {
        theme: "blue",
    },
};
Enter fullscreen mode Exit fullscreen mode

Fixing "Property Does Not Exist On Type"

Welcome to our second challenge! We're working with a user object featuring a single property, 'name,' set to 'Matt.' When we introduce an age of 24, an error surfaces right beneath the age assignment:

Error Message: Property 'age' does not exist on type '{ name: string; }'.

Your task is to resolve this error while minimizing alterations to the existing runtime code. Let's find a solution together that keeps the essence of the current setup intact!

const user = { name: "Matt",};
user.age = 24;
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

- const user = { name: "Matt",};
+ const user: Record<string, string | number> = { name: "Matt",};
 user.age = 24;
Enter fullscreen mode Exit fullscreen mode

Fixing "X is Possibly Null Or Undefined"

In this challenge, TypeScript flags a potential 'id' null value. The task at hand involves unraveling why this error occurs and devising solutions.

Error Message: 'id' is possibly 'null'.

Numerous pathways exist to resolve this issue. Some pertain to TypeScript intricacies, while others involve runtime considerations. Let's explore various strategies to address this hiccup!

const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id");
console.log(id.toUpperCase());
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id");
- console.log(id.toUpperCase());
+ console.log(id?.toUpperCase());
Enter fullscreen mode Exit fullscreen mode

Fixing "Types Of Property Are Incompatible"

In this exercise, we have a routingConfig object which contains some routes. These routes are an array of objects, each with a path and a component property, both of which are expected to be strings. We also have a createRoutes function that takes this routingConfig, and maps it into a type.

Upon calling createRoutes with this routingConfig, a rather verbose error appears:

createRoutes(routingConfig); // red squiggly line under routingConfig

Argument of type '{ routes: { path: string; component: string | number; }[]; }' is not assignable to parameter of type '{ routes: { path: string; component: string; }[]; }'.
  Types of property 'routes' are incompatible.
    Type '{ path: string; component: string | number; }[]' is not assignable to type '{ path: string; component: string; }[]'.
      Type '{ path: string; component: string | number; }' is not assignable to type '{ path: string; component: string; }'.
        Types of property 'component' are incompatible.
          Type 'string | number' is not assignable to type 'string'.
            Type 'number' is not assignable to type 'string'.
Enter fullscreen mode Exit fullscreen mode

Your task is to decode the error message and enhance its readability, focusing on the problematic component: '12' in the code, which seems misplaced. Remember, the goal isn't to fix the error outright but to improve the clarity of the error message and ensure it accurately points to the specific line of code.

const routingConfig = {
  routes: [
    {
      path: "home",
      component: "HomeComponent",
    },
    {
      path: "about",
      component: 12,
    },
    {
      path: "contact",
      component: "ContactComponent",
    },
  ],
};

const createRoutes = (config: {
  routes: {
    path: string;
    component: string;
  }[];
}) => {};

createRoutes(routingConfig);

Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

const routingConfig = {
  routes: [
    {
      path: "home",
      component: "HomeComponent",
    },
    {
      path: "about",
      component: 12,
    },
    {
      path: "contact",
      component: "ContactComponent",
    },
  ],
};

const createRoutes = (config: {
  routes: {
    path: string;
- component: string;
+ component: string | number;
  }[];
}) => {};

createRoutes(routingConfig);
Enter fullscreen mode Exit fullscreen mode

Fixing "X Is Of Type Unknown"

In this exercise, We're tinkering with a function called 'somethingDangerous' that relies on chance (thanks to Math.random()). If lady luck favors a value above 0.5, brace yourself—it triggers an error, giving us a 50-50 chance of failure. To catch this mishap, we've got a safety net in place—a try-catch block. But here's the snag: we need to fine-tune the error message nested within that catch block.

Error Message: 'error' is of type 'unknown'.

Your goal is to grasp the cause behind this error and devise effective modifications within the catch block to accurately log the error message.

Consider using type checks such as instanceof or implementing type assertions. Experiment with various strategies to identify the most suitable approach!

const somethingDangerous = () => {
  if (Math.random() > 0.5) {
    throw new Error("Oh dear!");
  }
};

try {
  somethingDangerous();
} catch (error) {
  console.log(error.message);
}
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

const somethingDangerous = () => {
  if (Math.random() > 0.5) {
    throw new Error("Oh dear!");
  }
};

try {
  somethingDangerous();
- } catch (error) {
-  console.log(error.message);
- }
+ } catch (err: unknown) {
+  if(err && typeof err ==="object" && "message" in err){
+    console.log(error.message);
+  }
+  else{
+    throw error;
+  }
+ }
Enter fullscreen mode Exit fullscreen mode

Fixing "Expression Can't Be Used To Index Type X"

In our code, we've got an object called productPrices with three properties: Apple, Banana, and Orange, each associated with a price value. Additionally, there's a function named getPrice that receives a product name as input.

The intention of the getPrice function is to retrieve the price by accessing the productPrices object using the provided product name.

But, currently, there's an issue occurring when attempting to access the object within productPrices.

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ Apple: number; Banana: number; Orange: number; }'.

Let's unravel why this error keeps popping up. Good news: the fix lies in tweaking the type, not the runtime code. Let's dive in!

const productPrices = {
  Apple: 1.2,
  Banana: 0.5,
  Orange: 0.8,
};

const getPrice = (productName: string) => {
  return productPrices[productName];
};

Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

- const productPrices = {
+ const productPrices:Record<string, number> = {
  Apple: 1.2,
  Banana: 0.5,
  Orange: 0.8,
};

const getPrice = (productName: string) => {
  return productPrices[productName];
};
Enter fullscreen mode Exit fullscreen mode

Fixing "Property X Has No Initializer"

Alright, so here's the situation: We've got a User class, and inside it, there's this private property called username. But here's the snag:

Error Message: Property 'username' has no initializer and is not definitely assigned in the constructor..

What we need to do here is tweak the User class so that we can bid farewell to this pesky error. Ready for the fix? Let's dive in and make that happen!

class User {
  private username: string;
}
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

class User {
  private username: string;
+ constructor(){
+ this.username = "";
+ }
}
Enter fullscreen mode Exit fullscreen mode

Fixing "Conversion Of Type X May Be A Mistake"

Imagine a Dog interface and a cat object. The Dog interface specifies a sole feature—a boolean property named "bark." Meanwhile, our feline friend, represented by a cat object, proudly showcases a "purr" property set to true.

In essence, dogs are known to bark, while cats elegantly purr. It's only natural that TypeScript alerts us with an error when attempting to coerce the cat object into a Dog type. This error message bluntly states:

Error Message: Conversion of type 'purr: boolean' to type 'Dog' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property 'bark' is missing in type 'purr: boolean' but required in type 'Dog'.

Alright, here's the task: pinpoint what's causing this error and come up with a solution. The key? Make sure the Dog interface and the cat object have a common property that matches. That's the trick to sorting this out!

interface Dog {
  bark: boolean;
}
let cat = { purr: true };
let dog = cat as Dog;
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

interface Dog{
  bark: boolean;
}

let cat = { purr: true };
- let dog = cat as Dog;
+ let dog = Object.assign({}, cat, {bark: true}) as Dog;
Enter fullscreen mode Exit fullscreen mode

Fixing "Cannot Redeclare Block-Scoped Variable"

In this exercise, there's this folder we're working with. Inside 'index.js,' there's just one line of code that creates a 'name' variable using 'const.' Now, the snag we've hit is an error message that says:

Error Message: Cannot re-declare block-scoped variable 'name'.lib.dom.d.ts(27237, 15): 'name' was also declared here.

Your task is to tackle this hiccup by tweaking either something inside 'index.ts' or by making adjustments to the 'tsconfig.json' file. Let's sort this out together!

const name = "Matt";
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge:

+ import "assert";
const name = "Matt";
Enter fullscreen mode Exit fullscreen mode

Fixing "Could Not Find A Declaration File"

We're working on an exercise that has its own directory. In the index.ts file, there's an issue flagged under 'diff' that says:

Error Message: Could not find a declaration file for module 'diff'. Implicitly has an 'any' type.

Although the 'diff' package is listed in package.json and sits snugly inside the node_modules folder, TypeScript seems reluctant to let us utilize it.

To tackle this, let's carefully dissect the error message and use the information to resolve it.

import Diff from "diff";
Enter fullscreen mode Exit fullscreen mode

My Solution to this Challenge: Add the @type/diff definitions to the package.json dependencies

{
  "name": "example",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "dev": "tsc --watch"
  },
  "keywords": [],
  "author": "Matt Pocock",
  "dependencies": {
    "diff": "^5.1.0",
    "@types/diff": "^5.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Alright folks, it's time to conclude this post. I trust this information has been helpful and enjoyable for you as much as it was for me while writing it. Don't hesitate to drop any comments or questions below. Happy coding, colleagues!

❤️ Enjoyed the article? Your feedback fuels more content.
💬 Share your thoughts in a comment.
🔖 No time to read now? Well, Bookmark for later.
🔗 If it helped, pass it on, dude!

Top comments (0)