I have some .js
config files and a tsconfig for these files with checkJs: true
. A library (Terser) has the type:
ecma: 5 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020
In my config file, I have ecma: 2017
. TS considers its type to be ecma: number
. In a .ts
file, I can just use as const
. In a .js
file, is there any way to get TS to narrow 2017
to a constant?
CodePudding user response:
You can use a const assertion in jsdoc, as detailed in this issue
// let config: {
// readonly ecma: "2017";
// }
let config = /** @type {const} */ ({
ecma: "2017"
})
// Or
// let config2: {
// ecma: "2017";
// }
let config2 = {
ecma: /** @type {const} */ ("2017")
}
Note: the ()
around the expression you want to make const is required.
CodePudding user response:
I would do two things in a combination to ensure it is a constant:
First - make sure that the props is not changeable runtime nomatter what.
///config.js
const config = {
anotherProp: true,
ecma: 2017
};
Object.defineProperty(config, "ecma", { value: 2017, writable: false });
export default config;
Second create d.ts file to "tests" the typescirpt this prop is readonly
/// config.d.ts
type Config = {
anotherProp: string;
readonly ecma: 2017;
};
declare const conf: Config;
export default conf;
The result will be that the typescript will complain about changes
//ts error: Cannot assign to 'ecma' because it is a read-only property.ts(2540)
config.ecma = 6;
And even If you try to hack it - it will fail runtime:
//runtime error: Cannot assign to read only property 'ecma' of object '#<Object>'
(config as any).ecma = 6;
Playground link here: here