显然,打字稿允许您通过如下简单的赋值从类型中删除只读修饰符:
function foo(x: { readonly value: string }) {
x.value = "new value"; // This would fail, as it should
bar(x); // But this is okay?
}
function bar(x: { value: string }) {
x.value = "new value";
}
在我看来,这将使偶然更改只读字段变得非常容易,还是我错过了什么?我是否使用了只读错误?打字稿中是否有任何更严格的替代方法可以禁止这种行为?
编辑:由于这确实是它的工作方式,因此以下变通方法似乎对我的特定情况有所帮助,尽管这绝不是完美的解决方案:
type ConstAware<T> = { __writable: true } & { [P in keyof T]: T[P] };
type Const<T> = T extends ConstAware<any> ? { readonly [P in Exclude<keyof T, "__writable">]: T[P] } : never;
type Foo = ConstAware<{
value: string;
}>;
function foo(x: Const<Foo>) {
let y: Foo = x; // Not allowed, yay
y.value = "new value";
}
答案 0 :(得分:1)
这是一个已知问题,已记录here。其要点是readonly
修饰符不会影响可分配性。不幸的是,这确实限制了readonly
修饰符的用途。
没有已知的方法可以使此更为严格,没有编译器选项,也没有巧妙的类型技巧来做到这一点。我对此声明非常有信心,因为无法辨别类型(条件或映射类型)上存在readonly
的类型系统。没有此功能,我们将无法真正引入不允许分配的错误。
注意这是在Typescript 3.1是当前版本时编写的,TypeScript的未来版本(希望如此)可能证明我错了。