Search code examples
typescripttypescript-generics

keyof doesn't return correct type when used with Record


I have a list of countries in an object

const CountryCodes = {
  DE: {
    countryCode: 'DE',
    countryName: 'Deutschland',
    phoneCode: 49,
  },
  US: {
    countryCode: 'US',
    countryName: 'United States',
    phoneCode: 1,
  },
  ...
}

And an interface for it's content

type CountryCode = {
  countryCode: string;
  countryName: string;
  phoneCode: number;
};

If I don't give a type to CountryCodes and get it's keys with keyof typeof CountryCodes it returns the correct result which is 'DE' | 'US' ...

But if i don't give a type there can be errors in this object, someone can add / substract an element. So i want to strictly type CountryCodes object with CountryCode type.

const CountryCodes: Record<string, CountryCode> = { ...

But with this type, result of the keyof typeof CountryCodes is now just string as stated in Record<string, CountryCode>

Is there a way where I can strictly type this object and still get the keys of countries with keyof?


Solution

  • Here's one way, where the data is first put in a temporary variable which is then assigned to the correct variable and "casted" to the wanted type:

    const _CountryCodes = {
      DE: {
        countryCode: 'DE',
        countryName: 'Deutschland',
        phoneCode: 49,
      },
      US: {
        countryCode: 'US',
        countryName: 'United States',
        phoneCode: 1,
      },
    }
    
    const CountryCodes: Record<keyof typeof _CountryCodes, CountryCode> = _CountryCodes;