Home > OS >  Typescript create type from array of months
Typescript create type from array of months

Time:08-13

Is it possible to generate a new type from an array in Typescript?

I have list of months in a variable, is there a way to generate a new type as MonthName: MonthNumber

For eg:

const Months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December',
] as const;

The output should be:

type MonthsWithNumber = {
'January': 01,
'February': 02,
'March': 03,
'April': 04,
'May': 05,
'June': 06,
'July': 07,
'August': 08,
'September': 09,
'October': 10,
'November': 11,
'December': 12
}

CodePudding user response:

In the answer below, I've renamed your Months array to monthNames.

The first step is getting a union of the string literals in your array. Let's call it MonthName:

type MonthName = typeof monthNames[number];

After that, creating the type is pretty easy: you can use the type utility Record<MonthName, number> to create an object-like type representing month names as property keys and their corresponding numbers as values. Creating the data structure isn't too difficult either, although it requires using a type assertion. That looks like this:

const monthNumberMap = Object.fromEntries(
  monthNames.map((name, i) => [name, i   1])
) as Record<MonthName, number>;

Putting it all together:

TS Playground

const monthNames = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December',
] as const;

type MonthName = typeof monthNames[number];

const monthNumberMap = Object.fromEntries(
  monthNames.map((name, i) => [name, i   1])
) as Record<MonthName, number>;

monthNumberMap.September
             //^? (property) September: number

console.log(monthNumberMap); /* Looks like:
{
  "January": 1,
  "February": 2,
  "March": 3,
  "April": 4,
  "May": 5,
  "June": 6,
  "July": 7,
  "August": 8,
  "September": 9,
  "October": 10,
  "November": 11,
  "December": 12
} */

CodePudding user response:

You could do something like this

      type monthType = {
           [key in typeof Months[number]]: number;
      };
  • Related