TypeScript – Type Predicates (Transcript)
Published on 2 Mar 2021 • 1 666 views (snapshot when curated).
Watch the original video on YouTube.
Transcript
00:00 — Servus friends, Andi here. Today we are going to demystify TypeScript’s type predicates and build a couple of custom guards together.
00:18 — Quick refresher: a type predicate is the foo is Bar
syntax you return from a function to tell the compiler “trust me, the argument is of type Bar when this is true.”
00:36 — I start with a Person | null
union. Inside an if (person)
block the compiler still thinks person
might be null. That’s where predicates shine.
00:55 — Let’s create a helper function isPerson(value: unknown): value is Person
. Inside the function we check the shape: typeof value === "object"
, the value exists, and the name
property is a string.
01:18 — Returning that boolean means everywhere we call isPerson(suspect)
TypeScript now narrows the type to Person
on the true branch.
01:38 — I demonstrate in VS Code: before the guard we have Person | null
, after if (isPerson(person))
the hover shows a clean Person
type.
01:58 — Predicates also work with arrays. I write function isPersonArray(value: unknown): value is Person[]
and reuse Array.isArray
plus every(isPerson)
.
02:20 — That means you can validate JSON payloads from APIs and get fully typed results without casting.
02:36 — Another pattern is discriminated unions. I have type Result = Success | Failure
. A predicate isSuccess(result): result is Success
checks the status
field.
02:58 — Inside the success branch I can access result.data
. Inside the failure branch I handle result.error
. No as
casting required.
03:18 — Important reminder: predicates only convince the compiler; they do not protect you at runtime unless the checks are correct. Always validate everything that comes from the outside world.
03:38 — In frameworks like React you can pair predicates with hooks. For example, const user = useUser()
may return User | undefined
. Guard once and you get strict typing everywhere downstream.
03:58 — Bonus tip: combine predicates with asserts
to throw early. A helper like assertIsPerson(value)
can throw an error while simultaneously narrowing the type for the remaining code path.
04:18 — That’s it! You now know how to roll your own type guards and make TypeScript work for you instead of the other way round.
04:30 — Danke fürs Zuschauen! Drop a comment if you want me to cover more advanced narrowing tricks or conditional types in a future video.