Step 8 – Type guards and type assertions in TypeScript

TypeScript provides a way to define and enforce types in our code. However, sometimes we may have a value that can have more than one type or we may not be sure about its type at runtime. This is where type guards and type assertions come in handy.

Type guards

Type guards are a way to check the type of a value at runtime, and change the type of the value accordingly. They can be implemented using the typeof, instanceof, and in operators.

typeof operator

The typeof operator returns a string that represents the type of a value. We can use it to check if a value is a string, number, boolean, or any other primitive type.

function logLength(value: string | number) {
  if (typeof value === 'string') {
    console.log(value.length);
  } else {
    console.log(Math.abs(value));
  }
}

logLength('Hello'); // Output: 5
logLength(-4); // Output: 4

instanceof operator

The instanceof operator checks if an object is an instance of a particular class. We can use it to check if a value is an instance of a class or an interface.

class Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

function greet(person: Person | string) {
  if (person instanceof Person) {
    console.log(`Hello, ${person.name}!`);
  } else {
    console.log(`Hello, ${person}!`);
  }
}

greet('John'); // Output: Hello, John!
greet(new Person('Sarah', 25)); // Output: Hello, Sarah!

in operator

The in operator checks if a property exists in an object. We can use it to check if a value has a particular property.

interface Square {
  kind: 'square';
  size: number;
}

interface Rectangle {
  kind: 'rectangle';
  width: number;
  height: number;
}

type Shape = Square | Rectangle;

function calculateArea(shape: Shape) {
  if ('size' in shape) {
    return shape.size * shape.size;
  } else {
    return shape.width * shape.height;
  }
}

calculateArea({ kind: 'square', size: 5 }); // Output: 25
calculateArea({ kind: 'rectangle', width: 5, height: 10 }); // Output: 50

Type assertions

Type assertions are a way to tell TypeScript the type of a value, even if TypeScript cannot infer it. They can be implemented using the as keyword or the angle-bracket syntax.

as keyword

The as keyword is used to tell TypeScript the type of a value.

const value: any = 'Hello';
const length = (value as string).length;

console.log(length); // Output: 5

Angle-bracket syntax

The angle-bracket syntax is an alternative way to tell TypeScript the type of a value.

const value: any = 'Hello';
const length = (<string>value).length;

console.log(length); // Output: 5

Type assertion vs type coercion

It’s important to note that type assertion is not the same as type coercion. Type coercion is when a value is automatically converted from one type to another by the JavaScript engine, based on a set of rules. Type assertion, on the other hand, is a manual way to tell TypeScript the type of a value.

const value: any = ‘5’;

// Type assertion
const numberValue = value as number;
const sum = numberValue + 2;

console.log(sum); // Output: 7

// Type coercion
const result = ‘5’ + 2;

console.log(result); // Output: ’52’

If we try to add a string and a number, JavaScript will coerce the string to a number, and return the sum.

const result = '5' + 2;

console.log(result); // Output: '52'

However, if we try to add a string and a number in TypeScript, we’ll get a compilation error, because TypeScript does not allow type coercion.

const result: number = '5' + 2; // Compilation error

We can use type assertion to tell TypeScript that we know what we’re doing, and that we want the result to be a string.

const result: string = ('5' as any) + 2;

console.log(result); // Output: '52'

Conclusion

TypeScript’s type system is one of its most powerful features, and type guards and type assertions allow us to work with values whose types may not be known at compile time. Type guards allow us to change the type of a value at runtime, while type assertions allow us to tell TypeScript the type of a value, even if TypeScript cannot infer it.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.