JS exported constants as TypeScript type

Issue

I work on a project with JS/TS mixed support
I’m looking for a way to reduce code duplication with JS string constants when wrapping them as Typescript types.

For example, I have constants for log type:

// logTypes.js    
export const ERROR = 'error'
export const INFO = 'info'

Reexport them:

// constants.js    
export * as LOG_TYPES from './logTypes.js'

And now I want to provide a TS type for this constants:

// types.d.ts
import { LOG_TYPES } from './constants'

export type LogType = ???

Obviously, I can declare the type like this and this will work:

// type LogType = "error" | "info", excellent
export type LogType = typeof LOG_TYPES.INFO | typeof LOG_TYPES.ERROR 

But I think this is redundant, and also creates two points to be maintainable when somebody needs to extend the set of constants.

So, actually I would like to write something like this:

// Does not work as desired
// type LogType = any, meh
export type LogType = typeof LOG_TYPES[string]

I know there is a difference between types and values, but this specific part of import/export should be statically analyzable so I think there should be a way to do this I don’t know about

Solution

That is the idea indeed, but typeof LOG_TYPES cannot be indexed by string, but keyof typeof LOG_TYPES:

type LogType = typeof LOG_TYPES[keyof typeof LOG_TYPES]
//   ^? "error" | "info"

Playground Link

Answered By – ghybs

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published