DEV Community

Fábio Englert Moutinho for Bitovi

Posted on

TypeScript Features Every Angular Developer Needs to Know

If you’re an Angular developer, you’re missing out if you’re not using advanced TypeScript features to help you build better code.

And it’s well worth the effort: TypeScript has some great features that can make you a stronger Angular developer. 💪

BigInt

BigInt lets you represent numbers bigger than 253. This is useful when you need to perform mathematical operations on very large integers. And you can work directly with large integer IDs and high resolution timestamps.

You can create a bigint primitive in two ways:

const n0 = 1n;
const n1 = new BigInt(1);
Enter fullscreen mode Exit fullscreen mode

There is no interoperability between bigint and number primitives, but they can be compared.

NOTE: BigInt support is only available for the esnext target.

Numeric Separators _

Numeric separators are great for readability. They don't change how the actual numeric value is interpreted.

 // which one is more readable?
const someNumber = 1782540173;
const anotherNumber = 1_782_540_173;
console.log(someNumber === anotherNumber); // true
Enter fullscreen mode Exit fullscreen mode

Keep in mind that you can't begin or end a number with a separator. Also, you can't use two in a row.

Private Fields

TypeScript has the private keyword that is stripped out during transpilation to JavaScript. If you need private properties at runtime, JavaScript's private fields come to the rescue. Unlike TypeScript's private keyword, private fields are prepended by a # character and are private even at runtime.

If you need private properties at runtime, this is now the way to do it in modern JavaScript.

NOTE: TypeScript will gracefully implement this for older browsers given your target is at least ECMAScript 2015 (ES6).

class Person {
 #age = 30;
 constructor(public name: string) {}
}
const someone = new Person('John');
console.log(someone.#age); // Property '#age' is not accessible outside class 'Person' because it has a private identifier.
console.log(someone['#age']); // Property '#age' does not exist on type 'Person'
Enter fullscreen mode Exit fullscreen mode

Operators

Nullish Coalescing ??

In JavaScript, nullish refers to a value strictly equal (===) to null or undefined.

A common pattern used in JavaScript when we want a default value is to use the OR operator ||.

function timeout(callback: Function, milliseconds: number): void {
 const wait = milliseconds || 100;
 setTimeout(callback, wait);
}
Enter fullscreen mode Exit fullscreen mode

Using the OR operator in this way can cause problems. Since we are dealing with numbers in the example above, then the value 0 will be a valid milliseconds value.
However, 0 is falsy, so the default value 100 will be assigned to wait.

It’s important to distinguish between falsy values (false, 0, empty string “”, and null/undefined) and nullish values (null/undefined). Nullish values are a subset of falsy values.

Nullish coalescing is an operator that returns a default value (the second operand) in case the first operand is nullish. If the first operand is not nullish, its value is returned.

Sounds complicated, but here's a simple example.

Consider a ?? b:

  • will return a if a is different than null and undefined
  • will return b if a is equal to null or undefined
let coffee: boolean | null | undefined;
const awaken = coffee ?? false;
Enter fullscreen mode Exit fullscreen mode

awaken will be assigned either coffee or false:

  • if coffee is not nullish, awaken will be assigned coffee
  • if coffee is nullish, awaken will be assigned false

Optional Chaining ?

Have you ever seen (or written) code like this?

if (obj && obj.prop1 && obj.prop1.prop2 && obj.prop1.prop2.prop3) {
 // do something
}
Enter fullscreen mode Exit fullscreen mode

Optional chaining changes how objects, properties and methods are accessed. Instead of throwing an error if they are nullish, it will short-circuit and return undefined. Optional chaining also makes your code more readable.

This is how we could rewrite the code above with optional chaining:

if (obj?.prop1?.prop2?.prop3) {
 // do something
}
Enter fullscreen mode Exit fullscreen mode

Non Null Assertion !

Sometimes, TypeScript is unable to identify that some operand is nullish. The non null assertion operator ! comes in handy for those cases. You might use it when you want to tell TypeScript that at that specific point in the code, the operand is definitely not null and not undefined.

// imagine you have a state that represents an API response
interface State {
 status: 'pending' | 'complete';
 response: string | undefined;
};
let state: State = {
 status: 'complete',
 response: 'some text',
}
// we know that when status is 'complete' we must have a response
if (state.status === 'complete') {
 console.log(state.response.length); // Object is possibly 'undefined'.
 console.log(state.response!.length) // this works
}
Enter fullscreen mode Exit fullscreen mode

Check out this post by Jennifer Wadella to learn more about the non null assertion operator in Angular.

Exponentiation **

In 2 ** 3, raises the first operand 2 to the power of the second, 3, being equivalent to 23.

Contrary to Math.pow(), the exponentiation operator ** works with the new BigInt values.

console.log(2 ** 3);
console.log(Math.pow(2, 3)); // the old way
Enter fullscreen mode Exit fullscreen mode

Assignment Operators **=, &&=, ||=, ??=

Assignment operators are shorthand for common assignment operations. For example, a += 1 is equivalent to a = a + 1.

Assignment operators apply an operator to two arguments, then assign the result to the left operand.

Additionally, the &&=, ||=, ??= operators will short-circuit, which means if the operation is evaluated to false, no assignment will occur.

a = a ** b; // a **= b, exponentiation
a = a && (a = b); // a &&= b, logical AND
a = a || (a = b); // a ||= b, logical OR
a = a ?? (a = b); // a ??= b, nullish coalescing
// a &&= b, also equivalent to:
if (a) {
 a = b;
}
// a ||= b, also equivalent to:
if (!a) {
 a = b;
}
// a ??= b, also equivalent to:
if (a === null || a === undefined) {
 a = b;
}
Enter fullscreen mode Exit fullscreen mode

These TypeScript techniques can help you handle nullish values, improve readability, manipulate larger integers, and more. I hope you find these TypeScript features useful for your Angular code!

To learn more about Angular and TypeScript, check out the Bitovi Academy.

Originally posted in Bitovi Blog

Discussion (7)

Collapse
mustapha profile image
Mustapha Aouas

I didn't know about the non null assertion. Thx for sharing :)

Collapse
stereosolar profile image
lazysergey

Actually it is considered a bad practice, there’s even esling/sonarlint rules for that
rules.sonarsource.com/typescript/t...

Collapse
fyodorio profile image
Fyodor

100%, can be very dangerous so better avoid it in real project

Collapse
saroj8455 profile image
Saroj Padhan

Thank you

Collapse
fashion86 profile image
Fashion86

That is some useful syntax. Thx

Collapse
wellington1993 profile image
Wellington Torrejais da Silva

Awesome!

Collapse
leolafon profile image
Leo Lafon

Most of these features are also available in JavaScript.

Thank you for sharing 👍