Using keyof with Record does not provide the accurate type

I created an object containing a list of countries with their respective country codes, names, and phone codes

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

In addition, I defined an interface for the content of this object

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

When retrieving the keys of CountryCodes using keyof typeof CountryCodes without specifying a type, it correctly returns 'DE' | 'US' ...

However, there is a risk of errors if no type is provided, as elements can be added or removed. To mitigate this, I decided to strictly type the CountryCodes object with the CountryCode type.

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

Unfortunately, after applying this type, the result of keyof typeof CountryCodes now merely returns string, following the definition in

Record<string, CountryCode>

Is there a way to enforce strict typing for this object while still being able to retrieve the keys of countries using keyof?

Answer №1

Let's explore a method of storing data by using a temporary variable before assigning it to the appropriate variable and converting it to the desired type:

const _Countries = {
  FR: {
    countryCode: 'FR',
    countryName: 'France',
    phoneCode: 33,
  },
  IT: {
    countryCode: 'IT',
    countryName: 'Italy',
    phoneCode: 39,
  },
}

const Countries: Record<keyof typeof _Countries, Country> = _Countries;

Answer №2

To ensure security, it is recommended to hardcode the valid keys:

type CountryKey = 'DE' | 'US';

const ValidCountryCodes: Record<CountryKey, CountryCode> = {

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: Axios encountered an issue with resolving the address for the openapi.debank.com endpoint

After executing the ninth command to install debank-open-api, I encountered an error while running the code in my index.js file. To install debank-open-api, I used the following command: npm install debank-open-api --save Upon running the following code ...

Utilizing custom colors in a Typescript/React/MUI Button component to enhance its design

How can I apply custom colors to the Button component without getting an error? Are there any possible solutions for this issue? I followed the module augmentation approach outlined in the documentation, but the problem persists: https://mui.com/material ...

TypeScript: "The type is generic and can only be accessed for reading." - Error code 2862

Consider this sample JS function that requires type annotations: const remap = (obj) => { const mapped = {}; Object.keys(obj).forEach((key) => { mapped[key] = !!key; }); return mapped; }; I am attempting to add types using generics (in ...

Implementing pagination within an Angular 11 Mat-table with grouping feature

Encountering an interesting issue with MatTable pagination and grouping simultaneously. I have two components each with a Mat-table featuring Pagination+Grouping. ComponentOne functions smoothly without any issues. When choosing to display 5 elements pe ...

The build process is encountering issues with lodash causing npm to fail

Utilizing Node: 16.20.2 Angular: CLI 11.2.5 Typescript: 4.1.5 @types/lodash: 4.14.177 An issue has arisen where the npm build process is failing with the following exception: Error: node modules/@types/lodash/common/object.d.ts:1026:46 error TS1 ...

Angular Nested Interface is a concept that involves defining an

Looking for guidance on creating a nested interface for JSON data like this: Any help is appreciated. JSON Structure "toto": { "toto1": [], "toto2": [], "toto3": [], } Interface Definition export interface Itot ...

The error message "Property 'xy' is not found within the type '{}'. TS2339" indicates that the 'xy' property is not present

I've embarked on setting up a compact project utilizing react / typescript featuring the components below: App.tsx import React from "react"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Styles ...

When the month changes in the React AntDesign Calendar Component, it automatically selects the last chosen day

My goal is to store the selected day in the state when a user clicks on a specific date. However, I am encountering an issue where the previously selected day remains saved in the state even after changing the month. Upon logging the onSelect event to the ...

Utilize various interfaces for a single object

I'm working on a Typescript project where I need to pass the same object between multiple functions with different interfaces. These are the interfaces: export interface TestModel { fileName:string, year:number, country:string } export interfac ...

Tips for enforcing strict typing in TypeScript when implementing abstract functions

Consider the following scenario with two classes: abstract class Configuration { abstract setName(name: string); } class MyConfiguration extends Configuration { setName(name) { // set name. } } In this setup, the name parameter in M ...

Angular has surpassed the maximum call stack size, resulting in a Range Error

I am facing an issue while trying to include machine detail and a button bar in my app. Interestingly, this setup has worked perfectly fine in other parts of the application but is causing errors in the core module. Here is the error message main.ts impo ...

The format must be provided when converting a Spanish date to a moment object

I am working on an Angular 5 project where I am converting dates to moment objects using the following code: moment(date).add(1, 'd').toDate() When dealing with Spanish locale and a date string like '31/7/2018', the moment(date) funct ...

Is there a way to consolidate two interface types while combining the overlapping properties into a union type?

Is there a way to create a type alias, Combine<A, B>, that can merge properties of any two interfaces, A and B, by combining their property types using union? Let's consider the following two interfaces as an example: interface Interface1 { t ...

React typescript wormhole is struggling to display content due to createPortal and useContext combination

Explore the interactive demo here. Purpose: The main objective is to have all children elements of PortalEntrance rendered beneath PortalExit. Main concept: PortalProvider provides a ref PortalExit assigns the ref to one of its child elements PortalEntr ...

What is the best way to implement persistStore in Redux-Toolkit?

Here is my setup: import AsyncStorage from '@react-native-async-storage/async-storage' import { persistStore, persistReducer } from 'redux-persist'; import { configureStore } from "@reduxjs/toolkit"; import { searchReducer } f ...

The package '@angular/[email protected]' is looking for a version of typescript that is greater than or equal to 2.4.2 but less than 2.6.0. However, it detected version 2.6.2 instead

Is there a way to resolve the issue with an existing Angular project? I want to use Typescript 2.6.2. @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f99a96948990959c8bd49a9590b9ccd7cbd7c9">[email protected]& ...

What is causing the failure of this polymorphic assignment within a typed observableArray in Knockout?

Consider a scenario where we have a class A and its subclass B. The goal is to assign an array of instances of class B to an array of instances of class A. While this works with normal arrays, the same operation fails when using ko.ObservableArray. import ...

Discover the method for converting a local file into a string

Looking to retrieve and read an SVG file in Angular 6 from the assets folder as a string. I've attempted the following: this._htmlClient.get('../../assets/images/chart1.svg').subscribe(data => { console.log('svg-file: ', ...

Implement Placeholder feature in ng2-ckeditor with the combination of Typescript and Angular 2.0

I am encountering an issue while trying to add the placeholder plugin to the CKEditor toolbar. When I include extraPlugins:'placeholder' in the CKEditor configuration, I receive the following error - Error: [CKEDITOR.resourceManager.load] Resou ...

having difficulty interpreting the information from angular's httpclient json request

After creating an Angular function in typescript to make an http request for JSON data and save it to an object, I noticed that the function requires two clicks of the associated button to work properly. Although the connection and data parsing are success ...