There is no index signature in the type 'string | number | EnvType' that accepts a parameter of type 'string'

Can someone help me troubleshoot this issue with config[curr][targetEnv] ???

interface EnvType {
  dev: string;
  staging: string;
  production: string;
}

type Config = {
  [key: string]: number | string | EnvType;
};

const config: Config = {
  networkTimeout: 10000,
  apiHost: {
    dev: 'http://localhost:8080',
    staging: 'https://staging.example.com',
    production: 'https://example.com',
  },
};

const targetEnv = process.env.TARGET_ENV || 'dev';

const mappedConfig = Object.keys(config).reduce((acc, curr) => {
  const currValue = config[curr];

  // check if value is not an object, return the value
  if (typeof currValue !== 'object') {
    return { ...acc, [curr]: currValue };
  }

  // if value is an object, retrieve value based on environment
  if (typeof currValue === 'object') {
    return { ...acc, [curr]: config[curr][targetEnv] }; // encountering an error here
  }

  // if none of the above conditions are met, do nothing
  return { ...acc };
}, {});

export default mappedConfig;

Answer №1

To start off, it is important to restrict the value of process.env.TARGET_ENV to only be either dev, staging, or production:

const targetEnv = (process.env.TARGET_ENV as keyof EnvType) || 'dev';

Next, ensure to cast config[curr] as EnvType within the typeof currValue === 'object' condition. This informs TypeScript that config[curr] will return the correct EnvType, and not a string or number when the if condition is satisfied.

// if object; fetch value by environment
if (typeof currValue === 'object') {
    return { ...acc, [curr]: (config[curr] as EnvType)[targetEnv] }; // error occurs here
}

The complete example looks like this:

interface EnvType {
    dev: string;
    staging: string;
    production: string;
  }
  
  type Config = {
    [key: string]: number | string | EnvType;
  };
  
  const config: Config = {
    networkTimeout: 10000,
    apiHost: {
      dev: 'http://localhost:8080',
      staging: 'https://staging.example.com',
      production: 'https://example.com',
    },
  };
  
  const targetEnv = process.env.TARGET_ENV as keyof EnvType || 'dev'; // added `as keyof`
  
  const mappedConfig = Object.keys(config).reduce((acc, curr) => {
    const currValue = config[curr];
  
    // if string, number, or boolean; simply return the value
    if (typeof currValue !== 'object') {
      return { ...acc, [curr]: currValue };
    }
  
// if object; fetch value by environment
if (typeof currValue === 'object') {
    return { ...acc, [curr]: (config[curr] as EnvType)[targetEnv] }; // added `as`
}
  
    // do nothing
    return { ...acc };
  }, {});
  
  export default mappedConfig;

Answer №2

When attempting to retrieve a value using a string key, it will successfully work for config[curr] due to the specified line in the config type:

[key: string]: number | string | EnvType;

However, the issue arises when attempting to replicate the same process within the EnvType object.

To resolve this, you must define the interface in a similar manner:

interface EnvType {
  [key: string]: string;
  dev: string;
  staging: string;
  production: string;
}

Subsequently, you may encounter an issue where config can be either a number or a string, both of which cannot be indexed in that way.

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

Unidentified object type detected - Material UI

This snippet of code was taken directly from the React Material UI website <Select id="selectedSubusecases" multiple value={stepsState.campaignOverviewStep.selectedSubUsecases} ...

What is the best way to interact with and modify the relationships of "many-to-many" fields in my database table?

As someone who is new to nestjs, I am working with two entities: @Entity({ name: "Books" }) @ObjectType() export class Book { @PrimaryGeneratedColumn() @Field() id: number; @Column() @Field() title: string; @ManyToMany(() => Auth ...

An error occured in angular2: Cannot access the 'title' property of undefined

Here is the code snippet for my custom component: export class MoviedetailComponent implements OnInit { movie:any constructor( private getmovie: GetmovieService, private router: Router, private rout: ActivatedRoute ) { } ngOnInit() { this.r ...

Show a specific form field based on the chosen option in a dropdown menu using Angular and TypeScript

I am looking to dynamically display a form field based on the selected value from a dropdown list. For instance, if 'first' is chosen in the dropdown list, I want the form to remain unchanged. However, if 'two' is selected in the drop ...

Guide to integrating global interfaces into your Nuxt project

Recently diving into the world of Nuxt 3, I've encountered a challenge while exploring TypeScript functionalities. My current goal is to create a versatile NavBar featuring multiple buttons with unique links. To achieve this, I aimed to establish an ...

Analyze the information presented in an HTML table and determine the correct response in a Q&A quiz application

I need to compare each row with a specific row and highlight the border accordingly: <table *ngFor="let Question from Questions| paginate: { itemsPerPage: 1, currentPage: p }"> <tr><td>emp.question</td></tr> <tr> ...

Guide for launching Electron on a local host server during development and for production builds

I have a project using Next.js + Electron + Typescript. I used the npx create-next-app --example with-electron-typescript command to generate the initial code. When I run npm run dev (which actually runs npm run build-electron && electron . ), the ...

Printing from a lengthy React DOM using window.print only generates a single page

My React component is capable of rendering markdown and can span multiple pages. Everything looks great when the component is displayed in the browser - scrolling works perfectly. However, whenever I try to print the page using window.print or ctrl + P, ...

Utilizing a TypeScript Variable as a Tagname in an HTML File within Angular

This specific problem is originally documented in this post. Despite being flagged as a duplicate, my scenario differs because the HTML content at hand is too extensive for utilizing innerHTML. The structure of my component's HTML file is as follows: ...

React-bootstrap-table Axios delete operation causing [object%20Object] to be displayed in the browser console

I am having trouble executing a delete operation using axios on a react-bootstrap-table, and encountering this error in the console DELETE http://localhost:9000/api/terminals/[object%20Object] Uncaught (in promise) Error: Request failed with status cod ...

Navigating through Angular using Typescript can sometimes lead to uncertainty when working with return data. This is where the

How do you handle a request with uncertain data and type checking? For instance, if you are making an HTTP call to an API where various data can be returned, but your component requires a specific data structure defined by an interface. Here's a sim ...

What is the process for exporting a plugin from dayjs() in JavaScript?

Currently, I have incorporated the plugin isToday() to enhance the capabilities of dayjs(). Nevertheless, I am uncertain about how to export isToday() in order to utilize it across other files. import isToday from "dayjs/plugin/isToday"; expor ...

jester: constantly jest navigator's mock & check against userAgent/vendor

Purpose: Need to iterate through different combinations of the userAgent Simulate navigator behavior Execute the test Observation: I simulated the navigator.userAgent, simulation works as planned, first test executes as expected Second simulation is per ...

RxJS emits an array of strings with a one second interval between each emission

Currently, my code is set up to transform an Observable<string[]> into an Observable<string>, emitting the values one second apart from each other. It's like a message ticker on a website. Here's how it works at the moment: const ...

The method beforeEach in angular2/testing seems to be failing as it is not

Currently, I am utilizing Gulp, Gulp-Jasmine, and SystemJS to conduct tests on an Angular2 demo application. The setup is fairly straightforward. I have successfully implemented a System.config block and loaded the spec file. However, I encounter an error ...

Arranging containers by invoking a function with material UI

I am completely new to material UI, typescript, and react, so if I make any mistakes or use the wrong terms please feel free to correct me. My goal is to place 4 boxes on a page, with three of them in a row and the fourth stacked below the first box. Curr ...

I am experiencing issues with the search feature in angular and node.js that is not functioning properly

Need assistance with debugging this code. I am currently working on adding search functionality to my Angular web page. However, when testing the code in Postman, I keep receiving the message "NO USER FOUND WITH USERNAME: undefined". Additionally, on the w ...

Error: Unable to access the 'registerControl' property of the object due to a type mismatch

I'm struggling to set up new password and confirm password validation in Angular 4. As a novice in Angular, I've attempted various approaches but keep encountering the same error. Seeking guidance on where my mistake lies. Any help in resolving t ...

The process of sorting through an array of objects based on their specific types in TypeScript

I am working on a function that filters an array of objects based on their type property: export const retrieveLayoutChangeActions = (data: GetOperations['included']) => data.filter(d => d.type === 'layoutChangeAction') as Layou ...

Transferring information through parent-child components via onChange

I have a question regarding data binding. In my project, I have a parent component and two child components: Parent: directives: [firstChild,secondChild], template:' <first-child [showList]="showList" (emitShowList)="getShowList($event)"& ...