Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to create a Typescript type based on the keys/values of a dictionary?

Is there a way to automatically generate a type based on a dictionary value? E.g. given this dictionary of constant values:

export const SHIPMETHODS: OptionsMap<UpsShipMethodOption> = {
    'UPS': 'GND',
    'UPS AIR2': '2DA',
    'UPS 3DAY SELECT': '3DS'
}

Is there a way to automatically generate a type like this, without having to duplicate everything?

export type ShipMethodOptionMap = {
    'UPS': 'GND',
    'UPS AIR2': '2DA',
    'UPS 3DAY SELECT': '3DS'
}

Unfortunately keyof doesn’t seem to work since it’s an object and not a type, so this doesn’t work:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

export type UpsShipMethodOption = keyof SHIPMETHODS // Doesn't work

I also tried using mapped types with a predeclared union type of the keys, but it doesn’t work either:

/* 
  Type 'KeyOptions' is not assignable to type 'string | number | symbol'.
  Type 'KeyOptions' is not assignable to type 'symbol'.ts(2322)
*/
export type OptionsMap<KeyOptions> = {
    readonly [Property in KeyOptions]: string;
}

export const SHIPMETHODS: OptionsMap<UpsShipMethodOption> = {
    'UPS': 'GND',
    'UPS AIR2': '2DA',
    'UPS 3DAY SELECT': '3DS'
}
export type UpsShipMethodOption = 'UPS' | 'UPS AIR2' | 'UPS 3DAY SELECT'

I have a bunch of such dictionaries, and most of them are quite large (30+ keys). Duplicating the dictionary into a type everywhere would make it a pain to maintain in case the values change, so any help with this would be great!

>Solution :

I think you just want the typeof operator. It simply gets the type of a value.

const SHIPMETHODS = {
    'UPS': 'GND',
    'UPS AIR2': '2DA',
    'UPS 3DAY SELECT': '3DS'
} as const // as const is important.

type ShipMethodOptionMap = typeof SHIPMETHODS 
/*
type ShipMethodOptionMap = {
    readonly UPS: "GND";
    readonly 'UPS AIR2': "2DA";
    readonly 'UPS 3DAY SELECT': "3DS";
}
*/

type UpsShipMethodOption = keyof ShipMethodOptionMap
// type UpsShipMethodOption = "UPS" | "UPS AIR2" | "UPS 3DAY SELECT"

Just note the as const on your object which allows typescript to infer the string literals so they can become part of the type.

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading