Last week I undertook another TypeScript-related issue which dealt with adding ESlint to the codebase with some guidelines given by the owner of the repo. I figured the issue would be easy enough, I've used ESlint before - how much different could it be? Well, it turns out it was a lot different than what I'm used to.
The Process
To begin, I installed ESlint by following their official quickstart guide. I was pretty surprised by how simple it was to set up for a TS project, but it ran me through some questions and in no time, ESlint was working!
I added the 2 rules that related with the repo owner's lint request which both related to importing files and types.
"rules": {
"@typescript-eslint/consistent-type-imports": ["error"],
"no-restricted-imports": ["error", {
"patterns": ["*.ts"]
}]
}
So, after adding the rules, I went through the standard procedure and linted everything by using npx eslint .
with only 11 errors showing up... which was great, it should be an open-and-shut issue. Pretty much every linting error had to do with a type of any
being used. I decided to look up the error and found out that typescript has support for a type called unknown
. The official documentation even states "unknown
is the type-safe counterpart of any." which is exactly what I needed!
So I got around the errors by changing all the any
types to unknown
. It was then that I realized this was going to be a whole lot harder than I initially thought. A lot of the object property calls were throwing errors because technically, it would be unknown if anything would exist on there. For example:
typeof value.name !== 'string'
.name
would throw an error because, to the compiler, it doesn't exist on value.
Unfortunately for me, I didn't think like that when I first encountered the error, though it did give me some practice with casting and assertions in TS / JS so there's always a bright side.
I read in the documentation and in a lot of discussions on stack overflow that unknown
types must first be funnelled into a more concrete typing before use. In order to fix the error, I decided to cast value almost every single time it was called to the expected object type. While not necessarily wrong, it was being done in functions that would check the type of an abstract object. If two objects had different structures, the function would still return false if it didn't match but it's overall just poor code conduct.
Feedback
After submitting the initial PR, the repo owner pointed this out to me.
I ended up overcomplicating a relatively easy fix both computationally and semantically. Thankfully, the repo owner was nice about it and gave some feedback for the requested changes. I applied those changes, opting for null checks which was in line with standard ESlint rules. I then had to change a function heading to take a generic type which after doing so, everything worked perfectly fine.
The PR still has yet to be merged and I'll definitely update the article once it has but for the time being, everything is done.
Progression since Hacktoberfest
This PR was the first time I've used ESlint with TypeScript and also the first time I've ever used the unknown
type. It was a painful but necessary experience and it felt good to finally understand the ins and outs of this foreign type. It really goes to show that issues themselves might sound easy, but you'll almost never know what you'll run into until you take the first step.
Closing thoughts
These PRs were a fantastic learning experience and I'm glad to have chosen them as the ones I would tackle this month. Moving forward there's still so much I want to learn and contribute to. For now, I'd love to take a look at adding custom themes or dark modes to websites, as I've never really added such a functionality before. I'm more excited to try custom themes as I would assume they aren't as solved as dark mode considering how many npm packages must exist that do just that. Thank you all for reading and until next time, see ya!
Top comments (0)