我有一些大的对象,比如
const a={
b:33,
c:[78, 99],
d:{e:{f:{g:true, h:{boom:'selecta'}}}};/// well, even deeper than this...
而且我希望TS不要允许我这样做
a.d.e.f.h.boom='respek';
我怎样才能完全固定物体?是仅通过为每个深层嵌套对象创建“readonly”接口和接口?
最佳答案 如 https://www.typescriptlang.org/docs/handbook/interfaces.html中所述,您可以在类/接口属性上使用只读或Readonly< …> / ReadonlyArray<>用于不可变对象和数组.在您的情况下,这将如下所示:
const a: Readonly<{
b: number,
c: ReadonlyArray<number>,
d: Readonly<{
e: Readonly<{
f: Readonly<{
g: boolean,
h: Readonly<{
boom: string
}>
}>
}>
}>
}> = {
b: 33,
c: [78, 99],
d:{e:{f:{g:true, h:{boom:'selecta'}}}}
}
a.d.e.f.h.boom = 'respek'; // error: Cannot assign to 'boom' because it is a constant or a read-only property.
显然,这是相当重言的声明,所以我建议你为你的对象定义合适的类结构.只是声明一个嵌套的无类型对象,你并没有真正利用任何Typescript的功能.
但是,如果你真的需要没有类型定义,我认为唯一的方法是定义一个冰箱(喜欢这个术语:D),就像Hampus建议的那样.取自deepFreeze(obj)函数from MDN:
function freezer(obj) {
Object.getOwnPropertyNames(obj).forEach(name => {
if (typeof obj[name] == 'object' && obj[name] !== null)
freezer(obj[name]);
});
return Object.freeze(obj);
}
const a = freezer({
b:33,
c:[78, 99],
d:{e:{f:{g:true, h:{boom:'selecta'}}}}});
a.d.e.f.h.boom='respek'; // this does NOT throw an error. it simply does not override the value.
tl; dr:如果没有定义类型,则无法获得编译器类型错误.这就是打字稿的重点.
编辑:
这最后的陈述是错误的.例如,
let a = 1
a = "hello"
将抛出错误,因为类型隐式设置为数字.但是,对于readonly,我认为,您将需要上面定义的适当声明.