Vue2+CompositionAPI+TS报错:props不存在于Readonly{}类型(TS2339)
Vue2 + CompositionAPI 访问props属性报TS2339修复方案
问题环境
- Vue:2.6.11
- @vue/composition-api:1.6.2
- TypeScript:4.6.3
问题复现
组件代码如下,在setup函数中访问声明过的props.foo时,TS抛出类型错误:
<template> ... </template> <script lang="ts"> import { defineComponent, reactive } from '@vue/composition-api' export default defineComponent({ name: 'componentName', props: { foo: { type: Boolean, default: false } }, setup(props) { const state = reactive({ bar: props.foo // TS2339: Property 'foo' does not exist on type 'Readonly{}>' }) return { state } } }); </script>
报错原因
@vue/composition-api 1.6.2版本内置的类型定义未完全适配TS4.6+的泛型推导逻辑,运行时声明的props字段无法被自动推导到setup的入参类型上,TS会默认将props识别为只读空对象,访问自定义属性时就会触发不存在属性的报错。
修复方案
方案1:显式声明Props泛型(推荐,无版本兼容问题)
给defineComponent传入显式的Props类型泛型,手动标注props的类型结构,不需要升级依赖:
import { defineComponent, reactive } from '@vue/composition-api' // 显式定义props类型 interface Props { foo: boolean } export default defineComponent<Props>({ name: 'componentName', props: { foo: { type: Boolean, default: false } }, setup(props) { // 此时props.foo可被正确识别为boolean类型,无报错 const state = reactive({ bar: props.foo }) return { state } } });
方案2:升级CompositionAPI版本
@vue/composition-api 1.7.0及以上版本已经修复了TS4.6+的类型推导兼容问题,升级后无需修改业务代码,即可自动从运行时props声明推导类型:
# npm执行 npm install @vue/composition-api@latest # yarn执行 yarn upgrade @vue/composition-api@latest
方案3:临时类型断言(不推荐长期使用)
如果暂时无法升级依赖或调整类型定义,可以通过类型断言临时绕过校验,但会丢失props的类型自动检查能力:
setup(props: { foo: boolean }) { const state = reactive({ bar: props.foo }) return { state } }
不推荐使用
props as any的写法,会完全丢失所有props的类型校验,增加潜在bug风险。
注意事项
- 所有CompositionAPI相关的方法(包括
defineComponent、reactive、ref等)必须从@vue/composition-api包导入,不要从核心vue包导入,否则会出现类型推导冲突 - 如果项目中同时使用了
vue-property-decorator等Vue2 TS生态包,需要确认其版本与@vue/composition-api版本匹配,避免全局类型污染
内容的提问来源于stack exchange,提问作者Minseo Lee
相关产品推荐
相关产品推荐

