Vue2升级Vue3后readonly修饰符报错(TS1042)的解决方法
Vue3 defineComponent中使用readonly修饰符报错TS1042的解决方法
问题
将Vue2项目升级至Vue3后,在defineComponent配置中使用TypeScript的readonly修饰符定义错误提示常量时,出现编译错误:
'readonly' modifier cannot be used here.ts(1042)
原因
TypeScript的readonly修饰符仅支持在类属性或类型/接口定义中使用,无法直接作用于普通对象字面量(如defineComponent的配置对象)的属性上。Vue3组件选项的顶层属性不兼容这类TypeScript语法。
解决方案
1. 模块级常量定义(推荐)
错误提示文本属于静态不变的常量,无需挂载到组件实例,直接在组件外部用const定义即可,天然具备只读特性:
// 组件文件顶部定义只读常量 const percentagePayableInvalidErrorMsg = "Percentage payable value is invalid."; const percentagePayableEmptyErrorMsg = "Percentage payable value cannot be empty."; const gstInclusiveRequestedAmountInvalidErrorMsg = "Total amount (GST Inclusive) is invalid."; const gstInclusiveRequestedAmountEmptyErrorMsg = "Total amount (GST Inclusive) cannot be empty."; const gstRequestedAmountInvalidErrorMsg = "Total gst amount is invalid."; const gstRequestedAmountEmptyErrorMsg = "Total gst amount cannot be empty."; const gstRequestedAmountLessThanCheckErrorMsg = "Total gst amount cannot be larger than total amount (GST Inclusive)."; export default defineComponent({ name: 'SubmitExpenseClaim', components: { /* ... */ }, // 其他组件选项... // 模板中可直接引用这些常量,组件方法内直接使用即可 });
2. 挂载到组件实例(使用setup语法)
如果需要将这些常量作为组件实例的属性,建议改用Vue3的setup语法,结合Vue官方的readonly API(注意与TypeScript修饰符区分):
import { defineComponent, readonly } from 'vue'; export default defineComponent({ name: 'SubmitExpenseClaim', components: { /* ... */ }, // 其他组件选项... setup() { // 将错误提示包装为只读对象(不需要响应式可直接省略readonly) const errorMessages = readonly({ percentagePayableInvalidErrorMsg: "Percentage payable value is invalid.", percentagePayableEmptyErrorMsg: "Percentage payable value cannot be empty.", gstInclusiveRequestedAmountInvalidErrorMsg: "Total amount (GST Inclusive) is invalid.", gstInclusiveRequestedAmountEmptyErrorMsg: "Total amount (GST Inclusive) cannot be empty.", gstRequestedAmountInvalidErrorMsg: "Total gst amount is invalid.", gstRequestedAmountEmptyErrorMsg: "Total gst amount cannot be empty.", gstRequestedAmountLessThanCheckErrorMsg: "Total gst amount cannot be larger than total amount (GST Inclusive)." }); return { errorMessages }; } });
模板中使用示例:
<div>{{ errorMessages.percentagePayableInvalidErrorMsg }}</div>
额外修正提示
你的代码存在Vue3 Options API的规范问题:数据属性(如todayDate、expenseClaim等)不能直接放在defineComponent顶层,需移入data函数:
export default defineComponent({ // ...其他选项 data() { const todayDate = new Date(); return { todayDate, todayDateUTC: new Date(Date.UTC(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate(), 0, 0, 0)), expenseClaimCreatedDate: new Date(), initialExpenseClaim: { /* ... */ } as ExpenseClaimModel, expenseClaim: JSON.parse(JSON.stringify(this.initialExpenseClaim)) as ExpenseClaimModel, expenseClaimLines: [], initialExpenseClaimLinesCount: 1, isAdmin: false, isStandardUser: false }; } });
内容的提问来源于stack exchange,提问作者Kanchana Kariyawasam
相关产品推荐
相关产品推荐

