Typescript是否有配置可对对象引用赋值行为触发警告?
TypeScript 常量引用修改问题解决方案
TypeScript 本身没有内置专门针对「常量对象引用赋值」的独立警告开关,但是可以通过以下几种原生能力 + 工程化配置实现完全一致的效果,且不需要额外定义类或者产生冗余编译代码:
1. 用as const实现编译阶段深度只读检查
给初始常量对象添加as const声明,TypeScript 会自动将对象所有层级的属性标记为只读,任何直接修改属性、通过引用修改属性的操作都会在编译阶段直接报错:
const initObj = { a: false, b: 1 } as const // 直接修改初始对象会触发编译报错 initObj.a = true // 错误提示:无法分配到 "a" ,因为它是只读属性。 // 赋值给其他对象后通过引用修改也会触发编译报错 const initReducer = { init_obj: initObj } initReducer.init_obj.b = 2 // 错误提示:无法分配到 "b" ,因为它是只读属性。
如果需要匹配自定义接口,可以用Readonly工具类型包裹接口声明:
interface InitObj { a?: boolean b?: number } const initObj: Readonly<InitObj> = { a: false, b: 1 }
2. 运行时冻结兜底避免开发阶段意外修改
如果需要在运行时也阻止修改操作,可以给初始对象套Object.freeze,开发环境下修改会直接抛出异常,更早暴露问题,且不会产生额外的运行时负担:
const initObj = Object.freeze({ a: false, b: 1 })
3. 开启ESLint规则实现提前警告
如果想要在引用赋值阶段就收到提示,可以开启以下ESLint规则:
no-param-reassign:禁止修改函数参数,直接阻止Redux reducer中直接修改state属性的操作redux/immutable-state-invariant:Redux专用规则,主动检测reducer中的可变状态修改行为prefer-const:基础规则,避免可变的常量声明
Redux场景最佳实践补充
你当前的Reducer写法本身不符合Redux不可变更新规范,Object.assign(state.init_obj, payload)会直接修改原引用对象,正确的不可变更新写法如下:
function Reducer(action: IAction, state: IReducer = initReducer) { switch(action.type) { case 'test1': return { ...state, // 返回全新的init_obj对象,不修改原有引用 init_obj: { ...state.init_obj, ...action.payload } } default: return state } }
内容的提问来源于stack exchange,提问作者mjwrazor
相关产品推荐
相关产品推荐

