Type guards (value is T)

Custom checking functions that narrow the type at the call site.

On this page

Example

#
TypeScript
interface Course {
  title: string
  modules: number
}

function isCourse(value: unknown): value is Course {
  return (
    typeof value === 'object' &&
    value !== null &&
    typeof (value as Course).title === 'string' &&
    typeof (value as Course).modules === 'number'
  )
}

const data: unknown = JSON.parse('{"title":"Python","modules":12}')

if (isCourse(data)) {
  console.log(`${data.title}: ${data.modules} modules`)
}
Result
Python: 12 modules

Definition and usage

#

A type guard is a function that returns boolean, whose return type is written as a predicate: value is Course. If the function returns true, the compiler treats the value as having that type.

This lets you wrap a complex check in one place and use it just like the built-in typeof or instanceof. It’s especially useful with data from an API, checking the shape of objects, and filtering arrays.

Since TypeScript 5.5, the compiler can infer the predicate on its own for simple functions, for example x => x !== null passed to filter().

Syntax

#
Syntax
function isType(value: unknown): value is Type {
  return …
}

More examples

#
Filtering with narrowing
TypeScript
const values = ['HTML', null, 'CSS', undefined]
const names = values.filter((v): v is string => typeof v === 'string')

console.log(names)
Result
['HTML', 'CSS']

Good practices

#
  • A type guard has to actually check what it promises. The compiler trusts the predicate and doesn’t verify its logic.
  • For extensive validation of data from an API, it’s worth using a library like Zod, which generates both types and checks from a single schema.

Related entries

#

Spotted a mistake or missing an example? Write to us.