TypeScript Features Every Angular Developer Needs to Know
Tags: angular, typescript, javascript
Published: 2021-09-27 14:33:57

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. :muscle:

#BigInt
BigInt lets you represent numbers bigger than 2<sup>53</sup>. 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](https://www.smashingmagazine.com/2019/07/essential-guide-javascript-newest-data-type-bigint/).

You can create a `bigint` primitive in two ways:
```javascript
const n0 = 1n;
const n1 = new BigInt(1);
```
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.
```javascript
 // which one is more readable?
const someNumber = 1782540173;
const anotherNumber = 1_782_540_173;
console.log(someNumber === anotherNumber); // true
```
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).

```javascript
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'
```

#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 `||`.
```javascript
function timeout(callback: Function, milliseconds: number): void {
 const wait = milliseconds || 100;
 setTimeout(callback, wait);
}
```

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`
```javascript
let coffee: boolean | null | undefined;
const awaken = coffee ?? false;
```
`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?
```javascript
if (obj && obj.prop1 && obj.prop1.prop2 && obj.prop1.prop2.prop3) {
 // do something
}
```
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:
```javascript
if (obj?.prop1?.prop2?.prop3) {
 // do something
}
```

##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.
```javascript
// 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
}
```
Check out [this post](https://dev.to/bitovi/non-null-assertion-operator-in-angular-g5l) by [Jennifer Wadella](https://dev.to/likeomgitsfeday) 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 2<sup>3</sup>.

Contrary to Math.pow(), the exponentiation operator `**` works with the new BigInt values.
```javascript
console.log(2 ** 3);
console.log(Math.pow(2, 3)); // the old way
```

##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.
```javascript
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;
}
```

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](https://www.bitovi.com/academy/).

> Originally posted in [Bitovi Blog](https://www.bitovi.com/blog/typescript-features-every-angular-developer-needs-to-know)