Type-strict coding with TypeScripts "strict" mode
Tags: typescript, opensource, webdev, github
Published: 2023-11-27 22:25:14

Around 2 weeks ago, I decided to work on an [issue](https://github.com/google/blockly-samples/issues/2031) that was unrelated to a lot of what I've done previously. For some context, I've worked extensively in C and C++, which are generally type-strict languages. Though, when thinking about the copious amounts of time I've spent developing sites and such, I've never really utilized TypeScript nor its [strict mode](https://www.typescriptlang.org/tsconfig#strict). I became so used to the untyped freedom and tedium that came with JavaScript that I decided to dive into the complete opposite end of the spectrum. It was a fun experience working in TypeScript and strict mode reminded me a lot of working in VS with C/++. Anyhow, here's the process I went through while working on this issue.

## The Process

Thankfully, the issue itself gave me a direct link to the documentation for strict mode. I took a look and sifted through some of the checks and requirements for enabling and maintaining a strict-mode codebase, and then shortly got to work. 

I browsed the folder that contained the blockly plugin and went straight into the `tsconfig.json` for it to enable strict mode, simple and easy. After doing so, I ran `npm run build` which showed many of the errors I had to fix because of strict mode type checks.

Many of these errors were simple enough, `TS2531: Object is possibly 'null'.` simply refers to a check for null that must be done to ensure a null value isn't utilized when it's not expected. Other errors like `TS2564: Property 'minimapWrapper' has no initializer and is not definitely assigned in the constructor.` simply mean something is declared in a class but is not nullable, therefore they must be assigned in the constructor. It's funny seeing a lot of exceptions and errors that I would run into in C++ appear in code that is almost JavaScript, almost uncanny to me, but this also meant I had a decent idea as to how to fix them.

For example, a lot of the cases were solved with the following:

```ts
  // old
  protected minimapWrapper: HTMLDivElement;
  // new 
  protected minimapWrapper: HTMLDivElement | null = null;
```

This simple change means that the variable can now expect to be null by default, meaning there's no need to assign anything in the constructor. However, this creates its own slew of additional issues. Now that we know we can expect `minimapWrapper` to be null, what happens when we are actually expecting a value? Well, that's where `null` checks come into play. Luckily there are many different ways to handle this. Whenever the code requires minimapWrapper to have a value, strict mode will yell at us UNLESS we include this simple check:

```ts
if(!minimapWrapper) {
  // Do something...
}
```

This was essentially the majority of the changes that were needed for everything to work, though there was a strange issue that occurred in the testing files. 

For some odd reason, a reference to the DOM was not being linked, meaning that tests on the specific functionality of the plugin could not be done due to needing a DOM reference to grab the positions of objects. After doing some digging, I found that adding

```js
const jsdom = require('jsdom');
const { JSDOM } = jsdom;

const { document } = (new JSDOM('')).window;
global.document = document;
```

to the top of the file fixed everything, most likely because we're forcing the reference to the DOM to be made by assigning it through an empty HTML doc.

## Changes Requested, Changes Made

After submitting my initial [PR](https://github.com/google/blockly-samples/pull/2078), explaining what was changed, and some info on the `npm run test` issues I was facing, various changes were requested. A lot of them were very simple changes, whether it be to make something not nullable and instead assign it in a constructor or fixing up the formatting of a certain function. The PR still hasn't been merged, but it's most likely due to the issue with running the tests, the reviewer said they would extensively look into it.

## Progression since Hacktoberfest

This was the first time I've made pretty big changes to an existing, and complex codebase. It came with a lot of surprises and I was pleasantly surprised at how easy it was to understand everything right from the get-go.

## Closing thoughts

It was actually pretty fun working with TypeScript and I did enjoy making all the comparisons between it and C++. Seeing certain errors that I never would've expected to see in JS was pretty awesome and it really felt like I was programming in a very familiar yet different language. I look forward to trying my hand at some more TS projects. Thanks for reading and until next time, see ya!