---
title: Boolean Props Default to false, Not undefined
impact: MEDIUM
impactDescription: TypeScript expects optional boolean to be undefined but Vue defaults it to false, causing type confusion
type: gotcha
tags: [vue3, typescript, props, boolean, defineProps]
---
# Boolean Props Default to false, Not undefined
**Impact: MEDIUM** - When using type-based `defineProps`, optional boolean props (marked with `?`) behave differently than TypeScript expects. Vue treats boolean props specially: an absent boolean prop defaults to `false`, not `undefined`. This can cause confusion when TypeScript thinks the type is `boolean | undefined`.
## Task Checklist
- [ ] Understand that Vue's boolean casting makes absent booleans `false`
- [ ] Use `withDefaults()` to be explicit about boolean defaults
- [ ] Consider using non-boolean types if `undefined` is a meaningful state
- [ ] Document this Vue-specific behavior for your team
## The Gotcha
```vue
```
## Why This Happens
Vue has special "boolean casting" behavior inherited from HTML boolean attributes:
```vue
```
This is by design to match how HTML works:
```html
```
## Solutions
### Solution 1: Be Explicit with withDefaults
Make your intention clear:
```vue
```
### Solution 2: Use a Three-State Type
If you actually need to distinguish "not set" from "explicitly false":
```vue
```
### Solution 3: Use null for "Not Set"
```vue
```
## Boolean Casting Order
Vue also has special behavior when Boolean and String are both valid:
```typescript
// Order matters in runtime declaration!
defineProps({
// Boolean first: empty string becomes true
disabled: [Boolean, String]
})
// → disabled = true
// → disabled = true
```
```typescript
defineProps({
// String first: empty string stays as string
disabled: [String, Boolean]
})
// → disabled = ''
// → disabled = ''
```
With type-based declaration, Boolean always takes priority for absent props.
## Common Bug Pattern
```vue
```
**Fix:**
```vue
```
## TypeScript Type Accuracy
The Vue type system handles this, but it can be confusing:
```typescript
interface Props {
disabled?: boolean
}
const props = defineProps()
// At compile time: boolean | undefined
// At runtime: boolean (never undefined due to Vue's boolean casting)
// TypeScript is technically "wrong" here, but the withDefaults usage
// or explicit false default can help align expectations
```
## Reference
- [Vue.js Props - Boolean Casting](https://vuejs.org/guide/components/props.html#boolean-casting)
- [GitHub Issue: Boolean props default to false](https://github.com/vuejs/core/issues/8576)
- [TypeScript Vue 3 Props](https://madewithlove.com/blog/typescript-vue-3-and-strongly-typed-props/)