I am looking to safeguard the constant object content from any changes during runtime. This includes alterations to both the object structure and its content. The preferred method for achieving this is by using Object.freeze.
interface iRO<T> {
readonly [key: string]: T | null;
}
const nc: iRO<HTMLElement> = {
main: document.querySelector("body"),
aside: document.querySelector("body > aside"),
}
const go: iRO<HTMLElement> = Object.seal({
main: document.querySelector("body"),
aside: document.querySelector("body > aside"),
})
const nogo: iRO<HTMLElement> = Object.freeze({
main: document.querySelector("body"),
aside: document.querySelector("body > aside"),
})
To exemplify, I have created three constants with identical content. The compilation succeeds with the constants "nc" and "go". However, the compiler raises an error with "nogo":
»Type 'Readonly<{ main: HTMLBodyElement | null; aside: Element | null; }>' is not assignable to type 'iRO'. Property 'aside' is incompatible with index signature. Type 'Element | null' is not assignable to type 'HTMLElement | null'. Type 'Element' is missing properties such as accessKey, accessKeyLabel, autocapitalize, dir, and more.«
This behavior is perplexing. Shouldn't Object.freeze have the same impact on the assigned type as Object.seal?
Explore the issue further in the Typescript Playground