Skip to content Paweł Grzybek

This is this — type predicates and assertion functions in TypeScript classes

Type narrowing in TypeScript allows the compiler to infer more specific types based on certain conditions. The typeof, in and instanceof operators are commonly used JavaScript constructs to narrow down the type of a variable or expression. Some methods are specific to TypeScript — type predicates and assertion functions are some of them. Let’s take a look at two examples.

let username: string | undefined;

// type predicate example
function isDefined(username: string | undefined): username is string {
  return username !== undefined;
}

// if user is defined, we will print it in uppercase
// otherwise we will throw an error
if (isDefined(username)) {
  // at this point, TypeScript knows that username is defined
  console.log(username.toUpperCase());
} else {
  throw new Error("Uuups. Dude is undefined.");
}
let username: string | undefined;

// assertion functions example
function isDefined(username: string | undefined): asserts username is string {
  if(username === undefined) {
    throw new Error("Uuups. Dude is undefined.");
  }
}

// if user is defined, we will print it in uppercase
// otherwise we will throw an error
isDefined(username)
// at this point, TypeScript knows that username is defined
console.log(username.toUpperCase());

Pretty cool, right? Perhaps you have used these concepts before. Only recently, I realized that they can be used in TypeScript classes as well, and the syntax is pretty funky — this is this 🤯

class Product {
  constructor(public name: string, public price?: number) {
    this.name = name;
  }

  hasPrice(): this is this & { price: number } {
    return this.price !== undefined;
  }
}
class Product {
  constructor(public name: string, public price?: number) {
    this.name = name;
  }

  hasPrice(): asserts this is this & { price: number } {
    if (!this.price) {
      throw new Error("No price");
    }
  }
}

That’s it for today. I hope you enjoyed it! 👋

Leave a comment

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!