Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 20, 2022 06:11 am GMT

Solve 'Not all code paths return a value in TypeScript' by properly using ReturnTypes | CodeReview Chronicles

Recently during a Code Review I noticed some code that raised my attention, although harmless.

const convertSomeValues = (val: string)  => {   if (val == "flour") {       return "bread"   }   else if (val == "apple") {       return "fruitsalad"   }   else if (val == "meat") {       // nope! I am vegetarian        return null   }   return null}

Can you spot what I found weird?

No, not the elseifs, nor that everything could have been a switch case or a Dictionary/Map (those were also other comments I made), but rather something more subtle:

Why do we have those return null?

Yes, if we are not supposed to return anything if there is no match, why do we have to return null? Can't we just drop that?

The developer replied that he tried exactly that but then typescript was complaining.

Typescript Compile Errors

TS Error

Not all code paths return a value in TypeScript

Yeah, that's true, my code does not return anything, can you freaking infer that, you stupid compiler?

Of course it could, if we tell him so.

A quick google search and we found out this option available for typescript config file:

NoImplicitReturns

When enabled, TypeScript will check all code paths in a function to ensure they return a value.

Ok, so the solution, is just disabling that!! Yay!

Mmm.. not really.

Rules rules rules...

Or maybe yes, but, as opinionated as Linter Rules ( or Typescript configurations) can be, I usually become very suspicious and want to know more, because, if someone was so bothered to create such a rule, maybe there is a valid reason.

And this rule makes absolutely sense, because it allows us to catch some nasty errors. Especially when having to do with loops, or when refactoring some code from/to arrow functions it might happen that the return is forgotten and things start behaving weird.
Imagine this:

const convertValues = (val: string)  => (val == "flour") ? "bread" : nullconst convertMoreValues = (val: string)  => {   if (val == "flour") {      "bread"   }   // todo add cases stuff here}

If we convert this simple arrow function with ternary operator (and default return) into a proper bracketed method, because for example we want to add other conditions, and we forget to add the return, the if block won't return anything and everything would break.

That's why imho it's not a good idea to disable noImplicitReturns.

What can we do then?

Do we need to stick with return null everywhere?

Dig deeper

First of all we should start considering if our method makes sense: probably an Error would be more meaningful or at least a string explaining why there is no match.

const convertValues = (val: string) => {    switch (val) {        case "flour":            return "bread"        case "apple":            return "fruitsalad"        case "meat" :            throw new Error('PreferVegetarianDietError')        default:            throw new Error('NoMatchFoundError')    }}

But let's assume that for some reason, due to legacy implementation we can't throw errors nor return other values, our method should simply convert something but just ignore all the rest. In this case returning nothing is acceptable.

But, shouldn't we make it more explicit?
How can we tell the developers using our method ( and therefore Typescript too) that our method can indeed return a string or nothing?

Well, by using Return Types!

const convertSomeValues = (val: string): string | void  => {   if (val == "flour") {       return "bread"   }   if (val == "apple") {       return "fruitsalad"   }}

Here I used void because we were really not interested in the result. Either it was a string or who cares, if you really need to have a null or undefined value, well, then you can use Return Type string | null and then stick to your return null ( but at least this has more visibility and meaning).

Recap

If you find yourself with Typescript nagging about your return types:

  • double check your methods, you are indeed likely forgetting something.
  • start considering your method from another perspective. Can you improve readability and developer experience being more specific with Types?
  • use noImplicitReturns ( or event @ts-ignore ) to tell TS to shut up ( but I would advise against it).
  • don't just stop and cure the symptom, but always try to find the cause and the reasons for something.
  • remember, Code Reviews are not battles, are learning opportunities, for both parties involved.

Hope it helps


Original Link: https://dev.to/dvddpl/solve-not-all-code-paths-return-a-value-in-typescript-by-properly-using-returntypes-codereview-chronicles-15fb

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To