Home > OS >  Typescript create type from string array and object
Typescript create type from string array and object

Time:10-20

I have this static array that may grow over time. Eg maybe in a month I will add another entry.

const GROUPS = ['Objects', 'Things', 'Stuff']

All of these refer to an interface, such as

interface Group { name: string, level: number}

How do I make a TS type that maps it with only the allowed const strings?

type GroupType = {[key: GROUPS]: Group}

CodePudding user response:

First, in order for the compiler to keep track of the literal types of the elements of GROUPS and not just string, you should use a const assertion when you initialize it:

const GROUPS = ['Objects', 'Things', 'Stuff'] as const;
// const GROUPS: readonly ["Objects", "Things", "Stuff"]

You can see that GROUPS's type is now a readonly tuple consisting of literal types.

Once you do that you can define GroupType as a mapped type over the union of elements of the GROUPS array, by indexing into the type typeof GROUPS (using the typeof type operator) with a number index (since the type you get when accessing GROUPS[n] where n is of type number is a union of the element types):

type GroupType = { [K in typeof GROUPS[number]]: Group }
/* type GroupType = {
    Objects: Group;
    Things: Group;
    Stuff: Group;
} */

You could also write this out like:

type GROUPS = typeof GROUPS[number];
type GroupType = Record<GROUPS, Group>;
/* type GroupType = {
    Objects: Group;
    Things: Group;
    Stuff: Group;
} */

where we give a type named GROUPS to the element types of the GROUPS value, and we use the Record<K, V> utility type instead of the equivalent manually-written mapped type.

Playground link to code

  • Related