Cool Typescript features I've learnt over the years
We've used Typescript in a lot of projects and over time I've kept track of a few things I think are cool.
We use Typescript in multiple parts of our stack, Angular, NestJS and general bundles compiled by Webpack. But there are so many ways to do things and, over time, I've learnt a lot of tweaks that allow me to create cleaner and more maintainable code. So this article outlines some of the main points that I've learnt throughout my Typescript journey, I hope they help you as much as they helped me :)
1) TSConfig paths
Sometimes there's a class or module that you use throughout your code. The imports can get quite messy if you have deeply nested components or files. Here's where modifying the paths
key in the tsconfig.json
file comes in handy.
You can create a path to a specific file or folder. I'll outline how to do both and then show you how to use them in code. Here's an example of a tsconfig.json
file with a few paths defined.
The @config
path assumes there is a barrel file (This is described later in the article but assume an index.ts
exists). In this case, you can import any of the objects, types, etc that the barrel file exports.
The @logger
points directly to a file called logger.service.ts
and this makes it really easy to import my LoggerService
anywhere in the project.
The @modules
refers to a folder and allows you to simplify your imports. The example below should show why this is cool.
*** There is a downside ***
As with most awesome things, it's not really a one-size-fits-all solution. When you use paths and compile to .js
, your .js
files are unable to resolve the paths. To get this working again, you have to bootstrap a file that loads the paths. Check this Github Issue for instructions on how to do it.
It's not too difficult to get it working so I think the pros far outweigh the cons.
2) The spread operator
Sometimes, we want to combine multiple objects or copy one that already exists. The spread operator really makes merging objects a lot easier.
What's awesome about the spread operator is that the order matters in terms of which key takes priority. The keys that appear at the end overwrite the ones at the start.
There are plenty of places where this is useful. A few places we use it include:
- In
ngrx
to overwrite specific keys in the store while leaving the value of the rest. - To create a new object (with a new memory address) with the same values as the old one.
- In parameters in functions, this is super cool but I'll leave you to investigate this more. Maybe start here.
3) Configs using barrel files
Configs can be quite difficult to get right. If you are reading from a .env
file, you need to make sure that runs first before accessing the values. There's also the aspect of keeping configs as dynamic as possible, but when you use string paths to get the config, the IDE will not autocomplete for you. I found a pretty cool way to create a config but it's a bit too long to write out in this article, so check out my other article here.
4) Maps can use anything as a key
Okay this functionality is super awesome! Did you know that the Map
type can take anything as a key? It seems like it's not useful but we've been able to build some really cool decorators in Typescript because of it. An example is that you can use a class type as a key and attach metadata to that.
5) Object key names
You don't have to specify the key name in an object (when you're creating it) if the variable name has the same name. It's quite a small thing but it makes your code far more readable.
6) Partial types
Sometimes we don't need to pass in a full model but we do want to pass in some of it. In that case, we can use the Partial
type to make a function accept an object that has a subset of keys.
Now this would allow us to send in an object that has some of the keys but not all of them. However, this doesn't force certain keys to be there. So you can use other types to use some keys and not others. Check type-fest on GitHub for some useful type examples.
Conclusion
These are a few things that I've learnt over the years of working with Typescript. I'll keep this updated as and when I find more cool stuff.
Hope this helps :)!