x is T Custom Type Guards & Assertion Functions

Last updated: 2026-10-22

x is T Custom Type Guards & Assertion Functions

When built-in guards (typeof/instanceof/in) fall short, write your own guard function: declare its return type as x is T (a type predicate) and TypeScript narrows x to T in branches where the function returns true. Its sibling is the assertion function (asserts x is T), which does not return a boolean but throws on failure.

GroupNarrowing & Assertions
KindSyntax
Strict modeNot required

ℹ️ Info The editor transpiles TypeScript to JavaScript and runs it (no type checking); see each example's Output for type-check results.

📝 Syntax

// Type predicate: x is narrowed to T where the function returns true
function isFoo(x: unknown): x is Foo {
  return typeof x === "object" && x !== null && "foo" in x;
}

// Assertion function: throws when invalid; x is treated as T afterwards
function assertFoo(x: unknown): asserts x is Foo {
  if (!isFoo(x)) throw new Error("not a Foo");
}

⚙️ Parameters

x is TType predicate return type: parameterName is TargetType. The function body must perform a real runtime check
asserts x is TAssertion function return type: throw on failure; code after the call treats x as T

Returns:A predicate function is an ordinary boolean function at runtime; narrowing happens at compile time. An asserts function returns nothing (void) at runtime and signals failure by throwing.

▶ Example

Edit the code below and click Try it to see the transpiled result:

Output:

failed: 404
data: x,y

(Runtime output after transpilation; once isFailure returns true, res is narrowed to ApiError and res.data type-checks — narrowing is guaranteed statically by tsc, at runtime there are only values)

💡 Notes

ℹ️ Info x is T only changes the compiler's view — at runtime it is a plain function. The body's checks must match the declared T, otherwise you are lying to the compiler.
⚠️ Note A wrong guard goes undetected by the compiler: declaring res is ApiError while checking unrelated fields lets the wrong type flow into the branch and blow up at runtime. Test your guard logic.
💡 Tip Type the parameter as unknown rather than any — unknown blocks all operations until narrowed, forcing you to write complete validation logic.
More cases coming soon.

📚 Related tutorials

❓ FAQ

Q What is the difference between x is T and returning plain boolean?
A With plain boolean the compiler has no idea what true means, so x keeps its old type after the call; with x is T, x is narrowed to T in the true branch. The predicate is type-only and adds zero runtime overhead.
Q When should I use asserts instead of is?
A Use asserts x is T when invalid data should terminate immediately (config loading, test assertions, environment checks) — it throws, and later code proceeds safely. Use is when you need if/else handling of both outcomes.
Q Is there an easier form since TS 4.4?
A Yes — since TS 4.4, aliased conditions let const isFailure = res.ok === false narrow automatically, and such consts can be reused. Named guard functions are still the most reusable form, though.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏