narrowing Narrowing Basics (truthiness & assignability)

Last updated: 2026-10-22

narrowing Narrowing Basics (truthiness & assignability)

A union type packs several possibilities into one variable, so before using it you must figure out what it actually is at that moment — shrinking the wide type down to a concrete one is called narrowing. TypeScript analyzes control flow (if, switch, truthiness checks) and automatically narrows the variable to the matching branch, after which branch-specific members are safe to use.

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

function handle(value: string | number | null) {
  if (value == null) return;        // narrows away null/undefined
  if (typeof value === "string") {
    value.toUpperCase();            // value is narrowed to string here
  } else {
    value.toFixed(2);               // value is narrowed to number here
  }
}

⚙️ Parameters

== nullLoose equality filters out both null and undefined in one check — the most common null-narrowing idiom
truthinessA truthiness check like if (value) removes null, undefined, 0, "", false and NaN all at once

Returns:None — narrowing is compile-time control-flow analysis and emits no runtime code.

▶ Example

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

Output:

Hello, guest
Hello, guest
Hello, anonymous
Hello, Ada (length 3)

(Runtime output after transpilation; name.length is safe inside the last branch because tsc has narrowed name to string — at runtime you only see the value)

💡 Notes

ℹ️ Info Narrowing is purely compile-time: TypeScript tracks types along execution paths (control-flow analysis), and the transpiled JS contains no "narrowing code".
⚠️ Note Truthiness checks also filter out legitimate falsy values: 0, "" and false. When 0 is a valid value (prices, counts), prefer value != null or an explicit typeof check instead of if (value).
💡 Tip Narrowing is most reliable on local variables and consts; narrowing on object properties can be invalidated by function calls (TS can't know whether the call mutated it) — copy the property into a local, or use a type guard function.
More cases coming soon.

📚 Related tutorials

❓ FAQ

Q How is narrowing different from a type assertion (as)?
A Narrowing is inferred automatically from the checks you write, so checks and types stay in sync; an assertion is you manually declaring a type with no verification. Prefer narrowing whenever possible — a wrong assertion goes unchecked.
Q Why can obj.flag still be undefined after I already checked if (!obj.flag)?
A For property accesses TS does not keep narrowing across possible side effects — any intervening function call might mutate it. Copy the value into a const local first, then check it.
Q Can one check rule out both null and undefined?
A Yes: value == null (loose equality) filters out both at once; value != null is the inverse. Strict equality === would need two comparisons (=== null and === undefined).
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%

🙏 帮我们做得更好

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

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