Sean
Sean

Reputation: 721

Type literal from object value

Got an object of countries like this:

const countries = {
  AD: {
    name: "Andorra",
    native: "Andorra",
    phone: "376",
    continent: "EU",
    capital: "Andorra la Vella",
    currency: "EUR",
    languages: [
      "ca"
    ],
    emoji: "🇦🇩",
    emojiU: "U+1F1E6 U+1F1E9"
  },
  AE: {
    name: "United Arab Emirates",
    native: "دولة الإمارات العربية المتحدة",
    phone: "971",
    continent: "AS",
    capital: "Abu Dhabi",
    currency: "AED",
    languages: [
      "ar"
    ],
    emoji: "🇦🇪",
    emojiU: "U+1F1E6 U+1F1EA"
  },
...

I can derive a typescript literal union type for the keys like:

type CountryIsoCode = keyof typeof countries
// "AD" | "AE" | "AF" | "AG" | "AI" …

How can I get a type literal union of the country name values?

Upvotes: 0

Views: 52

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370679

A big problem is that the countries are typed as

{
  name: string,
  native: string,
  // ...

with only string, and not the names themselves. If you annotate the array as const, then the objects inside won't be widened - and the rest is trivial.

Just look up the CountryIsoCode on the countries type, and then you can navigate to the ["name"].

const countries = {
  AD: {
    name: "Andorra",
    native: "Andorra",
    phone: "376",
    continent: "EU",
    capital: "Andorra la Vella",
    currency: "EUR",
    languages: [
      "ca"
    ],
    emoji: "🇦🇩",
    emojiU: "U+1F1E6 U+1F1E9"
  },
  AE: {
    name: "United Arab Emirates",
    native: "دولة الإمارات العربية المتحدة",
    phone: "971",
    continent: "AS",
    capital: "Abu Dhabi",
    currency: "AED",
    languages: [
      "ar"
    ],
    emoji: "🇦🇪",
    emojiU: "U+1F1E6 U+1F1EA"
  },
] as const;
type Countries = typeof countries;
type CountryIsoCode = keyof Countries;
type CountryNames = Countries[CountryIsoCode]["name"];

Upvotes: 1

Related Questions