简体   繁体   中英

How can I build a Typescript string literal type with an imported array?

In one of my config files config.js file, I have:

module.exports = {
    locales: ['en', 'fr']
}

In my library, I try to import the config.js file and turn it into a typescript liberal type like so:

import config from "config.js"

const tempDefaultLocales = [...config.locales] as const
export type Language = typeof tempDefaultLocales[number]

But the type of Language is string and not "en" | "fr" "en" | "fr"

If I don't import and just hard type it, the as const works. Example:

const locales = ["en","fr"] as const
type Language = typeof locales[number]

Gives me the correct type of "en" | "fr" "en" | "fr"

Any idea how I can make this work without changing my config file to ts or hardcoding it?

Here is a sandbox: https://codesandbox.io/s/awesome-swirles-ij4qsg?file=/src/App.tsx

PS: I can't change the config to ts because the config file is actually next.config.js and they don't allow us to change it and I want to avoid having 2 config files to set my languages. Thanks

Adding this as a new answer as it's a different approach.

Try to markup the exported JS with the correct JSDoc annotations, which should be read by TS:

module.exports = /** @type {const} */ ({
    locales: ['en', 'fr']
})

This was supported since 4.5. See here . Working codesandbox.

在此处输入图像描述

Define the exported object as a const. Working example here .

module.exports = {
    locales: ['en', 'fr']
} as const

as const does not "propogate". You cant define another variable somewhere else that isn't a const and then assume it will treat it as one because the as const guarantees are missing on the source data, so typescript can't guarantee it won't change or be added to by some other code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM