How to extract types from objects

Viewed 1284

I have a map:

const Map = {
  key1: 'value1',
  key2: 'value2'
}

I want to create a type value1 | value2 using the above object. Is it possible without repeating the values?

I tried type MyType = Map.key1 | Map.key2, but it throws the following error: Cannot find namespace 'Map'

4 Answers

First you have to declare the MyMap variable as const.

const MyMap = {
  key1: 'value1',
  key2: 'value2'
} as const

This tells typescript that the string literals in the object should be specific constants instead just inferred as string.

Now you can get the type of that object with the typeof keyword, then index that type by it's own keys to get all possible values:

type MyMapValues = typeof MyMap[keyof typeof MyMap] // "value1" | "value2"

const a: MyMapValues = "value1"
const b: MyMapValues = "value2"

// Error: Other values not allowed:
const c: MyMapValues = "value3"

Playground

const MyArray = [
    { name: "Alice", age: 15 },
    { name: "Bob", age: 23 },
    { name: "Eve", age: 38 }
];
type T = (typeof MyArray)[number];

const data = {
  value: 123,
  text: 'text',
  subData: {
    value: false
  }
};
type Data = typeof data;

Indexing the map will only get the value, and not the actual type. Using this, you can get the type of the values

const myMap = {
  key1: 'value1',
  key2: 'value2'
}

type myType = typeof myMap["key1"] | typeof myMap["key1"] 

To make your keys as the type, they need to be fixed or defined or say const.

So, you can make the type as follows:

const Data = {
  key1: 'value1',
  key2: 'value2'
} as const;

type DataType = typeof Data[keyof typeof Data];

Playground Link

Related