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

Define a type for strings that are keys in an object

I have a country configuration which looks as such:

type CountryConfig = {
   [country: string]: {
      countryCode: string,
      callingCode: string,
      ...
   }
}

const balkanCountries: CountryConfig = {
   Albania: { countryCode: "AL", callingCode: "+355", ... },
   Bulgaria: { countryCode: "BG", callingCode: "+359", ... },
   Croatia: { countryCode: "HR", callingCode: "+385", ... },
   ...
}

I want to create a type from the keys of balkanCountries:

type BalkanCountry = keyof typeof balkanCountries

Expected type: BalkanCountry = "Albania" | "Bulgaria" | "Croatia" | ..., actual type: BalkanCountry = string | number.

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

Based on the answer in this Stack Overflow thread this is expected behaviour and I can get around the number type by explicitly extracting the string as such:

type BalkanCountry = Extract<keyof typeof balkanCountries, string>

However, the output type I get is still type BalkanCountries = string and not a union of literals.

This means I can do assignment as:

const currentCountry: BalkanCountry = "Spain" // typescript will not throw error

Why this is happening? How can I ensure currentCountry can only be a value that is a key in balkanCountries?

Note: I am using TypeScript ~5.0.4.

>Solution :

You will have to drop the type definition to infer the keys from the object.

const balkanCountries = {
   Albania: { countryCode: "AL", callingCode: "+355" },
   Bulgaria: { countryCode: "BG", callingCode: "+359",  },
   Croatia: { countryCode: "HR", callingCode: "+385",  },
} satisifies CountryConfig;

type BalkanCountry = keyof typeof balkanCountries
// "Albania" | "Bulgaria" | "Croatia"

The satisfies operator (introduced in TS 4.9), will ensure the type safety.

TS 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