I've been getting myself familiar with the game of TypeScript for a while now, by contributing to a particular TypeScript (React|Next.js), and the experience has been well... cool
Some days ago, I improved a custom <Icon />
component I had built, by allowing it to receive props, a name
prop. So all you had to do, to use this prop is pass the name of the SVG icon as a value to it.
This is what it looked like:
In the snippet above, I'm extending the prowess of ReactSVG by passing the path to where our icons are located with the name
prop appended to it, in the string literal. Hence, using this component becomes like so:
Requiring more props
But, as time went on, the need to modularize — let me use the word "group" — our icons came up since they are local to a particular UI.
Creating a new folder in the "icons" folder was apparent. So, I did just that, and placed the necessary SVG files in it — Let's call this folder, dashboard-icons.
Modifying <Icon />
to accept a new prop that takes this new icon path as data became the next on my list. At first, I was a bit confused.
But, using the ternary operator saved the day. Take a look at the updated component below:
At first, I thought adding boolean
as a value to dashboard
would solve this issue of it being an optional prop, until I started getting build errors because TypeScript was screaming that the prop, dashboard
, is required.
So, I went on to use this component like so:
Making some props optional, correctly.
But, this approach of passing dashboard={false}
every time I want to use an icon that isn't in the dashboard-icons folder isn't optimal.
Why? Say, for example now, the project grows and we have more icons in their respective modules, We'll now have a component that looks like this"
This sorta destroys the DX — Developer Experience — of the next Dev that'll use this component in your team.
Luckily for me, I remembered the concept of optional chaining in JavaScript and my findings validated this concept.
Say we have a situation — a pretty common one — where we loop through the items in an array, and sometimes JavaScript throws an error saying that the array itself doesn't exist: cannot map over array (undefined) and so many blah blah blah.
Using this (?.
) operator when you loop over that array, helps you check if the array itself exists before returning the UI.
Sometimes, JavaScript will be JavaScript, and you may not even catch any error, if someItems
is undefined.
With TypeScript, all the props you want to pass to a component are supposedly required — by default.
So, modifying <Icon />
's dashboard prop to be optional with optional chaining was appropriate. Here's what the interface looks like now:
Scaling this component.
YES, I too was in doubt at first. The question: "If we begin to add more icon folders, how will this component handle them?" came up.
But, then I realized that I've been learning a lot, and concluded that we can chain ternary operations to accept multiple params or conditions.
So, the answer to that question is, add more conditions
Hence, this component can be used like this, without the optional props.
And if the need to use an icon from a specific folder arises, You'd pass the respective prop, say settings
for example.
Since all other props in the component's interface are optional, the default path will always be "/icons/${name}.svg"