boolean
Types the two values true and false — literally the union true | false.
let isDone: boolean = false;- Added in TypeScript 1.0
Errors
Assigning a non-boolean is a compile error: "Type 'string' is not assignable to type 'boolean'."
Changelog
- PHP 2.0Literal types true and false became usable in their own right, so boolean behaves as the union true | false in narrowing and in conditional types.
- PHP 4.4Control flow analysis of aliased conditions: a const holding a boolean narrowing check narrows the subject where it is used.
boolean is the type of the two values true and false. Under the hood it is not a primitive atom in the type system but the union true | false — and that matters more often than it sounds.
Consequences of being a union
- It narrows. Inside
if (flag)the type offlagistrue; in theelsebranch it isfalse. - It distributes in conditional types.
T extends true ? A : Bapplied tobooleanevaluates both branches and yieldsA | B, which is a common surprise when writing generic helpers. - The literal types
trueandfalseare usable on their own, which is what makes a boolean discriminant work:{ ok: true; data: T } | { ok: false; error: string }narrows onif (result.ok)exactly like a string discriminant.
Two things it does not do
It does not accept truthy values — "yes", 1 and [] are all errors where a boolean is required. And the capitalised Boolean is the boxed wrapper interface, which the handbook says never to use as an annotation; the Boolean(x) function is fine and returns a real boolean.
Example
When to use it
- Discriminating a result union on an `ok: true | false` field so the error branch is type-checked
- Coercing an unknown truthy value into a real boolean before storing it
- Writing a conditional type that must handle boolean distributing into both branches
Frequently asked questions
Is boolean the same as true | false in TypeScript?
Yes — `boolean` is exactly the union of the literal types `true` and `false`. That is why `if (flag)` narrows `flag` to `true` in one branch and `false` in the other, why boolean discriminants work in tagged unions, and why a conditional type applied to `boolean` distributes and returns both branches as a union.
Why can't I assign a truthy value to a boolean?
Because `boolean` accepts only the values `true` and `false`, not anything merely truthy — `1`, `"yes"` and `[]` are all type errors. Convert explicitly with `Boolean(x)` or `!!x`, which produce a real boolean. TypeScript still allows truthy values in `if` conditions; the restriction applies to assignment and arguments.
What is the difference between boolean and Boolean in TypeScript?
`boolean` is the primitive type; `Boolean` is the boxed wrapper interface and should never be used as an annotation. The `Boolean(x)` function, called without `new`, is unrelated and perfectly fine — it returns a primitive `boolean`. Avoid `new Boolean(false)` entirely: it produces an object, and every object is truthy.
More examples
A boolean discriminant narrows a result union
Prints `port 8080`, `failed: bad port: abc`, then `{ ok: true, data: 22 }`. Because `boolean` is `true | false`, the literal types `ok: true` and `ok: false` act as a discriminant: after `r.ok` is checked, TypeScript knows which member you have and exposes only that member's fields. Reading `r.data` before the check is a compile error.
type Result<T> =
| { ok: true; data: T }
| { ok: false; error: string };
function parsePort(raw: string): Result<number> {
const n = Number(raw);
if (!Number.isInteger(n) || n <= 0) return { ok: false, error: `bad port: ${raw}` };
return { ok: true, data: n };
}
function show(r: Result<number>): string {
// r.data here would be an error: it does not exist on the false branch
return r.ok ? `port ${r.data}` : `failed: ${r.error}`;
}
console.log(show(parsePort("8080")));
console.log(show(parsePort("abc")));
console.log(parsePort("22"));boolean distributing in a conditional type
Prints `yes no yes`, `[ 'yes', 'no' ]`, `yes no`. The types are erased at runtime, so the interesting result is `C`: passing `boolean` to a conditional type does not pick one branch — the union distributes and both are evaluated, giving `"yes" | "no"`. Wrapping the check as `[T] extends [true]` disables distribution when you want a single branch.
type Flip<T extends boolean> = T extends true ? "yes" : "no";
type A = Flip<true>; // "yes"
type B = Flip<false>; // "no"
type C = Flip<boolean>; // "yes" | "no" — both branches, because boolean is a union
const a: A = "yes";
const b: B = "no";
const c: C = "yes"; // "no" would also be accepted
function flip(v: boolean): "yes" | "no" {
return v ? "yes" : "no";
}
console.log(a, b, c);
console.log([true, false].map(flip));
console.log(flip(1 > 0), flip(1 > 2));
Discussion