我有一个界面:
interface Model {
pre: Vertices,
post: Vertices,
m: Matrix,
viewport: Vector,
halfViewport: Vector,
mouse: MouseState,
selection: boolean
}
我的应用程序中的状态对象是Model的一个实例,选择属性被初始化为false。请注意,没有只读装饰器:
const state: Model = {
...
selection : false
}
出于性能目的,模型值会更新到位,因为大多数属性都是引用类型。因此代码中有一些地方会更新属性,有些位于调用堆栈中。
现在,我注意到在顶级作用域中的函数中,更新Model对象的选择属性对我来说完全合法:
function draw(state){ state.selection =!state.selection ... }
我实际上并没有在我的代码中进行此调用,但是注意的关键我可以修改该选择属性,因为在堆栈中,在React组件事件处理程序中,我将尝试为selection
分配一个值:
function app (S: Model) : DOMElement<HTMLAttributes, Element> {
const props = {
...
onMouseDown: function (e: MouseEvent) : void {
...
S.selection = false
}
}
return React.DOM.div(props)
}
但是该分配会引发以下错误:
Uncaught TypeError: Cannot assign to read only property 'selection' of object '#<Object>'
起初我做了双重拍摄并检查了我在readonly
声明中没有写Model
,但我没有。当我查看Chrome调试器时,我发现S
处的对象已冻结(例如,tsc
调用`Object.freeze&#39; on things。我相信这与TS中的多余属性检查有关,其中接口实例在分配给变量或参数时会被检查,但是在这周围有什么呢?我可以在一个范围内实现突变而不是另一个范围,这似乎超级不一致
答案 0 :(得分:3)
我发现S处的对象被冻结(如,tsc在事物上调用`Object.freeze'。我相信这与TS中的多余属性检查有关,其中接口实例在分配给变量时会被检查参数,但是还有吗?
没有类似的事情发生。 TypeScript不会发出调用Object.freeze
的代码。当然,您可以自己阅读发出的JavaScript。除了删除类型注释并将ES6 +构造转换为等效的ES5代码之外,TypeScript从不做任何事情,其中任何一个都不包括在随机内容上调用freeze
。
其他东西冻结了这个物体。我怀疑您可能正在尝试在React state
对象上设置属性,而不是正确调用setState
,但如果没有完整的示例,很难说。