typescript - 扩展 BehaviorSubject 的只读存储
我在处理一个问题,该问题涉及存储在 BehaviorSubject 中的嵌套对象,这些对象允许在我正在开发的应用程序(RxJs 和 TypeScript 与 Angular)中进行变更。
我想通过创建一个新的类型 Store 来解决这个问题,该类型继承 BehaviorSubject,但确保存储的任何数据都是不可变的。
我最终得到了差不多这样的课程:
export class Store<T> extends BehaviorSubject<T> {
constructor(initialData: T) {
super(deepFreeze(initialData));
}
next(newData: T): void {
super.next(deepFreeze(newData));
}
getValue(): Readonly<T> {
return super.getValue() as Readonly<T>;
}
}
当我尝试像这样修改对象时,会给我一个运行时错误:
someStore$ = new Store({ firstLevel: { secondLevel: [] }});
someStore$.subscribe(val => val.firstLevel.secondLevel = ["que?"]);
然而,我也希望 TypeScript 能让开发者知道该操作是无效的,让 linter 告诉开发者他/她正在做一些非法的操作。
我该如何正确地做这件事?我是否必须以某种方式重写 Store 内的 subscribe 函数?我本希望通过在 getValue() 的返回类型上使用 Readonly 来解决问题,但上面的示例和下面的示例都没有给我任何 lint 错误:
someStore$.getValue().firstLevel.secondLevel = ["si!"]我该如何确保使用 TypeScript 通知这些对象的不变性,而不仅仅是在运行时出现错误?
作为参考,deepFreeze 的实现如下:
export function deepFreeze<T>(object: T): Readonly<T> {
const propNames = Object.getOwnPropertyNames(object);
for (const name of propNames) {
const value = object[name];
object[name] =
value && typeof value === "object" ? deepFreeze(value) : value;
}
return Object.freeze(object);
}
(基于 MDN 关于 Object.freeze 的文档)