withdefaults 是 vue 3 composition api 中为 defineprops 提供默认值的辅助函数,需与 typescript 类型声明分离使用:类型在 defineprops 中声明,默认值在 withdefaults 中指定,确保类型安全与运行时默认行为统一。

在 Vue 3 的 Composition API 中,withDefaults 是专门为 defineProps 提供默认值而设计的辅助函数,它与 TypeScript 类型系统天然兼容,能同时保证类型安全和运行时默认行为。关键在于:TS 类型声明写在 defineProps 里,而默认值写在 withDefaults 里,二者分工明确、互不干扰。
✅ 正确写法:类型与默认值分离
不能把默认值直接写在 TS 类型中(比如 foo?: string),那只是表示“可选”,不是“默认为某值”。必须用 withDefaults 显式指定:
- 先用
defineProps声明完整类型(含必填/可选) - 再用
withDefaults包裹它,并传入默认值对象 - TS 会自动推导出最终 props 类型(含默认值后的非可选性)
示例:
const props = withDefaults(
defineProps(),
{
count: 0,
disabled: false
}
)
此时 props.count 和 props.disabled 在 TS 中不再是可选类型,访问时无需非空断言或可选链。
⚠️ 常见错误:类型里写默认值 or 混用 default 选项
以下写法是错的或不推荐的:
-
count?: number+withDefaults(..., { count: 0 })✅ 可以,但?其实多余——withDefaults已让字段变为必填语义 -
count: number = 0❌ TS 不允许在接口/类型字面量中写默认值 - 用
defineProps({ count: { type: Number, default: 0 } })❌ 这是 Options API 风格,丢失 TS 类型精度,且无法做复杂类型推导(如泛型、联合类型)
? 处理函数、对象、数组等复杂默认值
默认值支持工厂函数,避免引用类型被共享:
- 基本类型(
string,number,boolean)可直接写字面量 - 对象、数组、正则、日期等引用类型,必须用函数返回新实例
- 函数类型默认值也建议用函数包裹,防止意外执行
示例:
const props = withDefaults(
defineProps
items: string[]
onClick: () => void
}>(),
{
config: () => ({}),
items: () => [],
onClick: () => {}
}
)
? 小技巧:利用 TS 类型推导简化书写
如果默认值逻辑简单,可以先定义默认值对象,再让 TS 自动推导 props 类型:
const defaultProps = {
count: 0,
disabled: false,
theme: 'light' as const
}
const props = withDefaults(
defineProps<typeof defaultprops title: string>(),
defaultProps
)</typeof>
这样既复用默认值,又保持类型精确(比如 theme 推导为字面量类型 'light' 而非 string)。











