Vue类型式Props声明中如何为复杂Prop设置默认值?
问题:为Vue组件的
complexProp设置默认值时出现TypeScript类型错误 错误信息
Argument of type 'HelloWorldProps' is not assignable to parameter of type 'InferDefaults<LooseRequired<HelloWorldProps>>'. Types of property 'complexProp' are incompatible.ts(2345)
原始代码
类型定义文件
<script lang="ts"> export type ComplextPropType = boolean | string | any[] | null; export interface HelloWorldProps { simpleProp?: boolean; complexProp: ComplextPropType; labels?: string[] // Vue docs example } export const HelloWorldPropsDefaults: HelloWorldProps = { simpleProp: false, complexProp: ((): ComplextPropType => null)(), //complexProp: ((): ComplextPropType => null), //complexProp: null, //labels: ()=> ['a', 'b'] // Vue docs mention something like this }; </script>
组件文件
<script setup lang="ts"> const props = withDefaults( defineProps<HelloWorldProps>(), HelloWorldPropsDefaults, // <-- 错误出现位置 ); </script> <template> <h1>{{ props.complexProp }}</h1> </template>
解决方案
问题核心在于withDefaults对非可选props的默认值类型要求:对于非可选且类型为联合类型、可空类型的props,必须通过工厂函数返回默认值,同时要避免错误的类型标注。
修正后的代码
类型定义文件
<script lang="ts"> export type ComplextPropType = boolean | string | any[] | null; export interface HelloWorldProps { simpleProp?: boolean; complexProp: ComplextPropType; labels?: string[]; } // 移除显式类型标注,让TS自动推导符合withDefaults要求的类型 export const HelloWorldPropsDefaults = { simpleProp: false, // 非可选的可空/联合类型props,用工厂函数返回默认值 complexProp: () => null, labels: () => ['a', 'b'] }; </script>
组件文件
<script setup lang="ts"> import { HelloWorldProps, HelloWorldPropsDefaults } from './your-props-file-path'; const props = withDefaults( defineProps<HelloWorldProps>(), HelloWorldPropsDefaults ); </script> <template> <h1>{{ props.complexProp }}</h1> </template>
关键说明
withDefaults要求:非可选的props如果类型包含引用类型、联合类型或null/undefined,必须使用工厂函数返回默认值,这是为了避免多个组件实例共享同一引用值的问题。- 不要给
HelloWorldPropsDefaults显式标注HelloWorldProps类型,因为withDefaults期望的默认值类型是InferDefaults<LooseRequired<HelloWorldProps>>,和原props接口类型不一致,自动推导类型可以完美匹配要求。 - 直接赋值
null或立即执行函数结果会触发类型不兼容错误,因为TS期望该属性是一个返回对应类型的函数,而非具体值。
内容的提问来源于stack exchange,提问作者MisterIsaak
相关产品推荐
相关产品推荐

