You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3升级至3.3.x后使用withDefaults触发TypeScript错误

Vue 3.3.x升级后withDefaults结合readonly非布尔Props的TypeScript错误问题

问题场景

将Vue 3版本从3.2.x升级至3.3.x后,使用withDefaults处理带有readonly修饰符的非布尔类型Props时,出现TypeScript类型不兼容错误,而布尔类型的readonly Props则可以正常运行。

报错代码示例

<script setup lang="ts">
interface Props {
  readonly title: string;
}

// 此代码正常运行
const props = defineProps<Props>(); 

// 此代码报错
const props = withDefaults(defineProps<Props>(), { title: '' });
</script>

错误信息

Argument type DefineProps<Props, BooleanKey> is not assignable to parameter type DefineProps<Readonly & {}, keyof Readonly & {}>

补充验证

  • 正常运行的布尔类型示例:
    withDefaults(defineProps<{readonly foo: boolean}>(), { foo: true });
    
  • 报错的非布尔类型示例:
    withDefaults(defineProps<{readonly foo: string}>(), { foo: 'foo' });
    

问题原因

这是Vue 3.3版本在类型推导逻辑上的小问题:当Props字段带有readonly修饰符且为非布尔类型时,defineProps返回的类型与withDefaults期望接收的参数类型出现冲突;而布尔类型因为Vue内部有特殊的类型处理逻辑,避开了这个冲突。

另外需要注意:defineProps本身会自动将所有Props设置为只读状态,不需要手动在interface中添加readonly修饰符,这也是官方推荐的写法。

解决方案

方案1:移除interface中的readonly修饰符

直接去掉Props interface里的readonly,defineProps会自动处理只读逻辑,不影响实际使用:

<script setup lang="ts">
interface Props {
  title: string; // 移除readonly
}

const props = withDefaults(defineProps<Props>(), { title: '' });
</script>

方案2:改用运行时Props定义结合类型声明

如果一定要保留interface中的readonly,可以通过显式的运行时Props定义来绕过类型推导问题:

<script setup lang="ts">
interface Props {
  readonly title: string;
}

const props = withDefaults(defineProps<Props>({
  title: {
    type: String,
    required: false // 由于设置了默认值,这里设为非必填
  }
}), { title: '' });
</script>

内容的提问来源于stack exchange,提问作者eXception

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:22:37