Universal interface for data type

I am currently working on developing a versatile function that can retrieve configuration settings based on an enum input. Within my modules, I aim to implement a method called getConfiguration that will provide me with all the necessary environment variables.

For instance:

enum PackageAEnvs {
   API_KEY = "API_KEY"
}

enum PackageBEnvs {
   ADMIN_URL = "ADMIN_URL"
}

My ideal setup would look something like this:

const getConfiguration = <T extends string[]> (conf: T): Record<T, string>{
     
  return conf.reduce( (acc, val) => {

    const env = process.env[val];

    if(! env) throw new Error()

    return { ...acc, [val]: env}

  }, {})

}

In this case, TypeScript should flag any errors if a key is missing:

const { randomKey} = getConfiguration<PackageAEnvs>() <-- TypeScript error expected

One approach I discovered involves using a specific type:

type Conf = "K1" | "K2"


type Config =  {[Property in  Conf]: string}

const getConfig = (): Config  => {

  return {
    K1: "2",
    K2: "2"
  }

}
const { someKey } = getConf() // <-- error

However, I'm attempting to figure out how to make the getConfig function generic enough to accommodate any type. Is this feasible?

Answer №1

To update your function, implement the following code:

const getConfiguration = <T extends object>(conf: T): Record<keyof T, string> => {
  return Object.keys(conf).reduce( (acc, val) => {
    const env = process.env[val];
    if(! env) throw new Error()
    return { ...acc, [val]: env}
  }, {}) as any
}

This revised function now accepts the enum as a direct parameter and generates a Record with enum keys as the keys. It utilizes Object.keys(conf) to fetch these keys during runtime.

const { API_KEY } = getConfiguration(PackageAEnvs)
const { ADMIN_URL } = getConfiguration(PackageBEnvs)

Playground

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

What is the procedure for including a js file in typescript?

I am trying to import a js file in typescript and access objects and functions within the file. I have added the js file in index.html, but it is not working as expected. I tried using "import '[js file path]'" but it did not work. import { Comp ...

Challenges with variable scopes and passing variables in Ionic 2 (Typescript)

In my Ionic 2 TypeScript file, I am facing an issue with setting the value of a variable from another method. When I close the modal, I get undefined as the value. I'm encountering difficulty in setting the value for coord. export class RegisterMapP ...

Tips for effectively invoking an API within a Next.js application

I've been exploring the most effective method for calling an external API within a Next.js application recently. Given my experience in developing MERN stack applications, I typically rely on axios for handling API requests and utilize it within a use ...

Using TypeScript and the `this` keyword in SharePoint Framework with Vue

I'm currently developing a SharePoint Framework web part with Vue.js. Check out this code snippet: export default class MyWorkspaceTestWebPart extends BaseClientSideWebPart<IMyWorkspaceTestWebPartProps> { public uol_app; public render(): ...

Creating Child Components in Vue Using Typescript

After using Vue for some time, I decided to transition to implementing Typescript. However, I've encountered an issue where accessing the child's methods through the parent's refs is causing problems. Parent Code: <template> <re ...

The global declaration of Typescript is only accessible within the node_modules/@types directory

Scenario As I develop an npm package using Typescript, I include types that are shipped alongside the library in the following structure: my-package |- index.js |- index.d.ts |- package.json The index.d.ts file includes global declarations like: declare ...

Trouble with Typescript in VSCode made easy

Setting up a VSCode environment for working with TypeScript v2.03 has been challenging. Beginning with a simple vanilla javascript snippet that can be tested in node via the integrated terminal. function Person() { this.name = ""; } Person.prototy ...

What is the process for adding a script to the head tag in Next.js?

I have a query regarding my current setup in next.js. I am using the src/app directory structure, and it seems that this arrangement does not allow for the use of next/head. Therefore, I would like to know how I can insert scripts and other tags into the ...

What is the best approach to implement global teardown with Playwright?

I have been struggling to implement a global teardown for Playwright, but I am unable to get it to execute. Despite following the guidelines provided in the documentation, the teardown function refuses to work. Although I do not have a setup command runnin ...

Testing React components within a controlled environment using cypress-react-unit-test

I'm currently facing a challenge in comprehending how to modify the props of a react component while utilizing cypress-react-unit-test. Below is a straightforward controlled input component: interface MyInputProps { inputVal: string onInputCh ...

The method toLowerCase is not found on this data type in TypeScript

I am currently working on creating a filter for autocomplete material. Here is an example of my model: export class Country { country_id: number; name: string; } When calling the web method ws: this.ws.AllCountry().subscribe( ...

What is the process of 'initializing' an object in TypeScript?

Is it possible that retrieving a json from a mongodb database and casting it does not trigger the typescript constructor? What could be causing this issue? I have a Team class export class Team { transformations: { [transformationId: string]: Transfor ...

Issue with Typescript: conditional return type failing to function

I am working with a function that has its return type determined by the arguments provided. const example = (flag: boolean): typeof flag extends true ? "yes" : "no" => { if (flag === true) { return "yes" } else { ...

Retrieving Status Text from an Angular 8 Http Service

My application includes a service that sends a POST request to a server: addPerson(person:PersonDTO) :Observable<any> { return this.httpClient.post<any>(this.urlBase + 'Persons', person); } When subscribing to the service in a comp ...

Jest has uncovered a single open handle that could prevent Jest from shutting down when utilizing ts-jest alongside webpack's node.js api

Attempting to create a test for a webpack 4 plugin using the webpack node.js API, but there is one persistent console message that I can't seem to shake off. Below is a simple code snippet of my test written with jest: webpack4.test.ts: import path f ...

Display streaming data continuously within an HTML page using Angular 16

Currently, I am actively developing a stream API that receives data with a 'Content-Type' of 'text/event-stream'. Below is a snippet from my stream.service.ts: connectToSse(): Observable<any> { return new Observable((observer ...

Issues with the inheritance functionality in styled components are causing errors

The issue arises when I try to customize the styling of my PrimaryButton component, separate from the DefaultButton. Despite writing style properties for it, the changes do not take effect. Here is the folder structure: https://i.stack.imgur.com/0KjyH.pn ...

Send a string to directive via HTML

Trying to implement a "clipboard" directive following this example. In my case, I need to dynamically compute the string to be copied to the clipboard. The goal is to pass the output of a function that generates the string to the directive. Currently, I ...

Distinguish private member unions in Typescript

Struggling with discriminating between private class member types? Attempting to access variables v1 and v2 using string literals resulting in type union issues. With a bit of tweaking, I found a workaround for public members only. Check out this example: ...

The issue of HTTP parameters not being appended to the GET request was discovered

app.module.ts getHttpParams = () => { const httpParamsInstance = new HttpParams(); console.log(this.userForm.controls) Object.keys(this.userForm.controls).forEach(key => { console.log(this.userForm.get(key).value) const v ...