Some Lesser Known TypeScript Features
In the past few years, TypeScript has become a popular way to write JavaScript apps. The language is immense and can do a lot of things.
Here’s a short list of some rarer TypeScript features you may not be aware of to help with your development:
- You can write numbers with underscores. For example,
1000000000
can be written as1_000_000_000
. It will be compiled to the regular number in Javascript, but using this syntax makes things easier to read. The underscores can be placed anywhere in the number although writing25
is more readable than2_5
. Another good use case for this syntax is monetary amounts.2545
may represent $25.45 in your app. This can be written as25_45
instead.
(As mentioned by a commenter on Reddit this is also a stage 2 Javascript proposal: https://github.com/tc39/proposal-numeric-separator) - If you know a variable is defined you can add a
!
after it to access it without first checking if the value isundefined
. For example, you may be injecting props into a React component using a decorator (e.g.@inject(router)
or@inject(store)
). You can now writethis.props.store!.someValue
even if the definition of store isstore?: Store
. Be careful not to overuse this feature, but there are times where it comes in handy. You can read here for further discussion of this problem. (You could always use anif
statement too, but that’s more verbose for cases you know the if statement is truthy). - You can set a variable to have type
never
. This means it can’t be set to anything. How is this useful? One place it can be useful is to check you’ve handled every possibility of a switch statement. For example:
export function unreachable(x : never) {
throw new Error(`This should be unreachable! but got ${x}`)
}const someFunction = (temperature: 'hot' | 'cold' | 'warm') => {
switch (temperature) {
'hot': console.log("it's hot outside!"); break;
'cold': console.log("it's cold outside!"); break;
default: unreachable(temperature);
}
}
The above code will throw a compile-time error, because it’s possible for unreachable()
to be called. If you add a switch case for warm
with a break after it, the compile error will go away as the default block can no longer be reached.
Another potential use case for never
is a function containing an infinite loop or a function that always throws an exception:
function loop(fn: Function): never {
while(true) fn();
}
Thanks to James Meyers in the comments for these use cases.
4. Another lesser used type you can use is unknown
. This just means we have no idea what the item we have is. This may happen if we’re calling a third party API for example. If we try do x.substr(0, 2)
it will throw a compile error. We can use an unknown
variable by first doing a type check. For example, writing if (typeof x === “string”) x.substr(0, 2)
would no longer throw an error.
unknown
is both very similar to any
and the complete opposite. They’re similar in so far as with both types we don’t know what the type is. They’re the complete opposite in that any
will never throw a type error, but unknown
will always throw an error until we identify what it is.
const x: any;
x.substr(0, 2); // doesn't throw a compilation error
const y: unknown;
y.substr(0, 2); // throws an error as we don't know what y is
if (typeof y === 'string') y.substr(0, 2); // doesn't throw an error
Looking for some more tricks, check out this post:
Know any other useful TypeScript tricks that should be included? Feel free to mention them in the comments!
About Me
I‘m a full-stack developer and founder of Skilled. Feel free to reach out at elie.tech or follow me on Twitter @elie222.
Newsletter
Stay up to date by subscribing to my newsletter.