Improving Perceived Code Quality in TypeScript

Oct 12, 2019

Code quality has been (and still is) a very hot button topic in the software engineering field. Many developers have differing ideas about how a piece of code will be written. Oftentimes, this causes a project's code velocity to grind to a halt because no one can agree on a way to proceed. I think these three tips will help alleviate that problem:

  1. Optimize for change and solving the current problem

it's easy to try to encapsulate all of the potential edge cases in one fell swoop, but life doesn't always work out that way. Write code in a way that makes it easy to update in the future. A great example of this concept is summarized by the wonderful Kent C. Dodds:

  1. Segregate business logic in the front end to the back end

A lot of the times I've seen front end code try to capture business logic in React applications. This is an anti-pattern, I feel because when your business logic changes, now engineers have to trawl through the codebase and find where the old business logic exists, then update it. Front end should only exist to display information retrieved from the back end and send updates. Maintaining this decoupling will make it much easier for your business to pivot and for engineers to maintain both back and front end codebases.

  1. Rockstar teams deliver good quality, not a single developer

Teams are what deliver good products. It makes sense to spread the knowledge evenly around a team and this team will be more balanced. This isn't to say that each team member may have his or her strengths, but the team as a whole will be much better equipped to pick up the slack should one teammate be away and they will also be able to cohesively move towards a solution that each member on the team understands. When all members of a team understand the end goal of having an application and understands the sum of its parts, it becomes much easier to deliver higher quality products.


With these three hypotheses in mind, I want to talk about what code quality means.

quality: character with respect to fineness, or grade of excellence

Quality may be found in code in three ways: ease of discovery, ease of updating, and legibility. A high quality codebase will have all three. Lower quality codebases may only have one or two. I realize that "ease of discovery" and "ease of updating" is highly subjective, but how often has the following scenario occurred to you?

A request has been put in to update a small piece of UI inside of a React application. An engineer (you) is tasked with the update. You find the data you need, edit the request or add another one to fetch it, then you pass it down as a prop. Then you discover that the request was made at the top level parent component and the result is drilled down layers six levels deep with inconsistent prop naming and some component props are passed through via {...props}. So now it's tough to follow where all the props are flowing through which component, it's also tough to debug if anything goes wrong. Oh, and this is one edge case. You need to address the same issue for three others.

Code problems are easy to solve. We can map older data models to newer ones that better express the shape and intent or optimize functional performance. What's more difficult and inherently more valuable to solve are architectural problems. Code is meant to be read and scanned by humans. Why make that task harder?


How do I improve my code quality?

Code quality is inherently coupled to what your project is trying to accomplish, but these three steps can help many projects towards improving their code quality:

  1. Identify areas of difficulty or ambiguity, then make them the simple and clear
  2. Write legible code
  3. Document your changes and project structure

Get to the point

Identifying areas of difficulty or ambiguity is easily the most conceptually challenging task on this list, but it's also the one that gives the most reward. Part of being a successful developer means that a successful developer can extrapolate from ambiguous or inconsistent sets of rules and create code that satisfies them and make them available to the rest of their team.

Any further examples would be incredibly expensive to discuss, as many examples would be based on the product being worked on, or some other business context. I'll introduce a general rule of thumb that I like to fall back on: If something doesn't make sense to you, chances are someone else doesn't understand it either. It's important to ask questions and frame it in a way that empowers non-developer people to give you the answer you need.

Write less terse code

const str: string = "10";

return +str;

Returning +str is probably less verbose than returning parseInt(str, 10), but it is less readable. Here's why: the + operator in JavaScript is the Unary Plus Operator, and it converts its operand to a number. This is considered a clever solution, but what happens if str is a prop that's passed down to it? If str is passed a value of "string", the unary plus operator will return NaN, but it won't throw an error. parseInt does have the same behavior, but which one do you think is more legible? I'd think the parseInt(). Code is meant to be human readable, and we have many compilers and transpilers that handle the responsibility of converting human code to machine code.

Here's a great article by James Shakespeare for further reading.

Documentation

Finally, documentation. I see the phrase "self-documenting code" thrown around a lot, and there is some merit to it with the advent of JSDoc and TypeScript. These tools definitely help to provide some context alongside code, which will almost always be the source of truth apart from your business rules, which are subject to change. However these tools do not give us the benefit of contextual documentation. They don't specify how various parts of the application work together. They don't explain often used commands or potential errors. I've ran into a few errors running the application, resolved the errors, and documented my fixes inside of the project README. It's simple to write, your team will appreciate your effort, and your future self will thank you for it.