Skip to content

Instantly share code, notes, and snippets.

@flacial
Created August 5, 2022 02:25
Show Gist options
  • Save flacial/6a548fd40910f96e1123e744e66e2a81 to your computer and use it in GitHub Desktop.
Save flacial/6a548fd40910f96e1123e744e66e2a81 to your computer and use it in GitHub Desktop.
TypeScript: type guard

type guard is a function that takes a type and returns a boolean. TypeScript uses it to determine if the element type can be narrowed down.

It's needed when we try to filter our data and end up returning a narrowed type. In the following case, we want filter to filter the array to only include elements that aren't a string.

interface User {
  email: string;
  userId: number;
  name: string;
}

const users = ['hi', 'hello', { email: 'wrong', userId: 1, name: 'mike' }]
const selectedPeople: (string | User)[] = [...users];

// Type guard that narrow down x type to User if the condition is true
const isUser = (x: string | User): x is User => typeof x !== "string"

/*
Type '(string | User)[]' is not assignable to type 'User[]'.
  Type 'string | User' is not assignable to type 'User'.
    Type 'string' is not assignable to type 'User'.
*/
const existingUsers: User[] = selectedPeople.filter((people) => typeof people !== "string");

It throws an error because it doesn't now that we're trying to narrow the type down to a User.

We solve it with a type guard!

interface User {
  email: string;
  userId: number;
  name: string;
}

const users = ['hi', 'hello', { email: 'wrong', userId: 1, name: 'mike' }]
const selectedPeople: (string | User)[] = [...users];

// Type guard that narrow down x type to User if the condition is true
const isUser = (x: string | User): x is User => typeof x !== "string"

// No error
const existingUsers: User[] = selectedPeople.filter(isUser);

existingUsers // [ { email: 'wrong', userId: 1, name: 'mike' } ] 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment