Get IntelliSense for your SVG icons library using Typescript
Some of the most satisfying things in life are the minor accomplishments you achieve, the ones that make your day-to-day work a little more fluent.
Suppose you use a custom SVG library for your icons. In that case, you probably experience this annoying routine: You copy the icon name from the design and try to display it to the screen. But the names do not exactly match 🤔 and you need to look carefully in the SVG index file 😒, or even try a few times before you hit the correct icon. 😠
Can we do better? If you are using Typescript — yes, we can!!
Type your SVG icons
So, you are building a design system or some other reusable component library for your team. One of the first things you need to take care of is the icons. If you use a custom SVG library, you probably index all the icons' paths in some file. We index these paths in a simple const object, and it's working just fine.
We decided to take a step forward and make our SVG library a little more convenient for the developers.
First, we use a class
to store the index with areadonly
property for each icon:
class AteraIcons { readonly home = './assets/svg/home.svg'; readonly user = './assets/svg/user.svg'; readonly chevron_down_bold = './assets/svg/chevron_down_bold.svg'; readonly close_x_thin = './assets/svg/close_x_thin.svg';}
Then we export an instance of the icon's class:
export const icons = new AteraIcons();
And here comes the magic — we convert the class keys to a type and export this type too:
export type AteraIcon = keyof AteraIcons;
Then in the icon component, we are using AteraIcon
to type the name instead of a generic string
.
@Input() set name(value: AteraIcon) { this._src = icons[value];}
This way we gain two benefits:
- Typing — developer can use only the icon name from our index. If a developer has even a tiny typo like using x instead of X — Typescript will fail to compile:
2. The IDE exposes us to IntelliSense 🕺
A few words about Typescript keyof
The operator keyof
is one of the little goodies of Typescript. It takes a type and produces a string literal of its keys.
We could achieve a closer effect by doing this:
export type AteraIcon = 'home' | 'user' | 'chevron_down_bold' | 'close_x_thin';
But instead of getting a long line with all your icons' names, we use the keyof
on the icon's class and connecting the class and its keys. Doing so, every time we add a new icon, we only need to add it to the class index.
keyof
can be used only on types, which is why we index the icons in a class and not in a simple const object.
BTW, you can use the same technique on every index you have. Nice, isn't it?