如https://www.typescriptlang.org/docs/handbook/interfaces.html 中所述,您可以在类/接口属性上使用readonly,或在不可变对象和数组上使用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 的任何功能。
但如果你真的需要不使用类型定义,我认为唯一的方法是像 Hampus 建议的那样定义一个冷冻机(喜欢这个词:D)。取自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:你不能在不定义类型的情况下得到编译器类型错误。这就是 Typescript 的全部意义所在。
编辑:
最后这句话是错误的。例如,
let a = 1
a = "hello"
会抛出错误,因为类型被隐式设置为数字。但是,对于只读,我认为您将需要如上定义的正确声明。