TypeScript Literal Type Guards and in Operator blog post

TypeScript Literal Type Guards and in Operator

Todd Motto

14 Aug, 2019

TypeScript

4 minutes read

Welcome back to the TypeScript Type Guards series! You’re entering the realms of next level knowledge, woohoo!

For reference, the 4 articles in this TypeScript series:

Enjoying the series? Come and master the whole TypeScript language with us across 2 courses, beginner concepts and finally advanced. Full of real-world examples, it’ll answer so many questions you have and will have. Click here to check out more of what you’ll learn with us!

In this post we are going to learn about Literal Type Guards and then we will learn how to use the in operator.

The in operator

The in operator is very interesting, it gives us the ability to say const exists = and then we could test something.

const exists = 'localStorage' in window;

If we run this in the browser this would result to true for browsers that have this 'localStorage' property on the window object. What it’s essentially saying is does the window object have a property called 'localStorage'. This is different to window.localStorage because this is looking up the value whereas the in window, and we’re checking this 'localStorage' as a string, is checking whether the property even exists. It doesn’t care about the value, the value could be false and this would result to true.

This is a brief introduction to the in operator, you’ll also see this with something like a for loop. Dos prop exist in object, if so we want to iterate it with a for loop.

for(const prop in object){}

Now let’s apply this to the code below.

class Song {
  constructor(public title: string, public duration: number) {}
}

class Playlist {
  constructor(public name: string, public songs: Song[]) {}
}

function isSong(item: any): item is Song {
  return item instanceof Song;
}

function getItemName(item: Song | Playlist) {
  if(item instanceof Song) {
    return item.title;
  }
  return item.name;
}

On our isSong() function we could return item. But before doing so we want to check if the title exists in our item. Now the item gets passed through, it could be a Song or it could be a Playlist.

function isSong(item: any): item is Song {
  return 'title' in item;
}

It is important to remember that 'title' in item; returns a boolean of whether the property exists or not. If the item in the title is available then we know that we are dealing with a Song.

Literal Types

In TypeScript we can create Literal Types, this means that the type is in fact a literal. If we did something like const foo = 'bar';, by default this would have a literal type of bar. We could change this by adding a type string const foo: string = 'bar';. So we have changed the type by manually typing this for ourselves.

Let’s now demonstrate this on the code above. If we take our Song class, even though this could be done on a type, object, interface. We are going to say that the kind here is of type 'song'. If we were to hover over this in our IDE we would see Song.kind: "song" so it’s a string literal.

class Song {
  kind: 'song';
  constructor(public title: string, public duration: number) {}
}

Similarly we can say we are having just a 'playlist'.

class Playlist {
  kind: 'playlist';
  constructor(public name: string, public songs: Song[]) {}
}

We can now go ahead and refactor the getItemName function. So instead of saying if it is a song and say if the kind of item equals a 'song'. Everything will be perfectly implied for because we are using structural typing with TypeScript.


function getItemName(item: Song | Playlist) {
  if(item.kind === 'song') {
    return item.title;
  }
  return item.name;
}

We have now learned how to use a literal type and we can use another Type Guard when we use that title and then in the item is our isSong function. The literal type is just another way we can detect a particular property or a type of something and then we can infer that type and that’s the key to remembering: we infer those types inside those conditional blocks such as an if statement.

About the author

Todd Motto profile picture

Todd Motto

GDE Google Developer Expert

Todd is the Founder of Ultimate Courses. With a passion for Angular, TypeScript and JavaScript, Todd leads the online courses creation and has written hundreds of articles on front-end web development and beyond. He specialises in breaking down complex topics and understands the critical mission of learning new technology fast, comprehensively and the right way.

Love the post? Share it!

Lots of time and effort go into all our blogs, resources and demos,
we'd love it if you'd spare a moment to share them!

Explore our TypeScript courses

Get started today and join over 60,000 developers.