DEV Community

Tim Mulqueen
Tim Mulqueen

Posted on

How to build Typescript String literal Types from Objects

With typescript 3.4 we get const assertions. This makes it easier to create enums from Javascript objects. Without const assertions its difficult to create a type with would be a String literal of some object values. It is however, fairly trivial to do this with keys.

const translations = {
    header_title: "DEV.to",
    footer_cta: "about us",
    header_subtext: "",
};

// "header_title" | "footer_cta" | "header_subtext"
type TranslationsKeys = keyof typeof translations;

But lets say that would to create a type based on the values of a constant. For example, in the case below we want the values of the routes rather the keys.

There is where const assertions come into play. In the example below if we did not have the as const the type of RoutesEnum would just be string.

const Routes = {
    home: "/",
    about: "/about-us",
    cart: "/cart",
};

type ValueOf<T> = T[keyof T];

 // string
type RoutesEnum = ValueOf<typeof Routes>;

Sometimes this is enough but not quite for our use case. The const assertion will make all the properties read only and turn them into String literals. We can then use the ValueOf function to create a type of all the values of the object.

const Routes = {
    home: "/",
    about: "/about-us",
    cart: "/cart",
} as const;

type ValueOf<T> = T[keyof T];

// "/" | "about-us" | "/cart"
type RoutesEnum = ValueOf<typeof Routes>;

Playground link

Glossary:
String literals
const assertions
keyof

Latest comments (2)

Collapse
 
lucianbc profile image
Lucian Boaca

Great point! I've been looking for this for a while. Thanks for showing it here!

Collapse
 
cubiclebuddha profile image
Cubicle Buddha

Yea when I saw const in the release notes for TypeScript I was kind of like “uh oh okay whatever.” But once I saw that I could use it for make an object of constants... well, it really blew my mind. Thanks for the reminder of what TypeScript makes possible.