Can dynamic string types be declared in Typescript?

Let's consider the following scenario:

export enum EEnv { devint, qa1 };
export type TEnv = keyof typeof EEnv;
export const env:Record<TEnv, {something:number}> = {
  devint: {
    something: 1,
  },
  qa1: {
    something: 1,
  },
}

Now, I aim to generate a dynamic object based on the env object, as demonstrated below:

export const SAVE_TOKEN: Record<TEnv, string> = {
  devint: "SAVE_TOKEN/devint", // derived from "env" key
  qa1: "SAVE_TOKEN/qa1", // derived from "env" key
}

Is it possible to define a type in such a way that it would be "SAVE_TOKEN/"+TEnv instead of just a plain string?

Answer №1

For those still searching for updates, the feature mentioned will now be included in version 4.1 of TypeScript. You can find more information at TypeScript#40336.

export type SaveTokenNamespace<K extends string> = { [T in K]: `SAVE_TOKEN/${T}` };

export function makeNamespace<K extends TEnv>(env: Record<K, unknown>): SaveTokenNamespace<K> {
  return Object.keys(env).reduce((ns, k) => ({ ...ns, [k]: `SAVE_TOKEN/${k}` }), {} as SaveTokenNamespace<K>);
}

console.log(makeNamespace(env));
const envNamespace = makeNamespace(env);
const test1: 'SAVE_TOKEN/qa1' = envNamespace.qa1; // Ok!
const test2: 'SAVE_TOKEN/notqa1' = envNamespace.qa1; // Error: Type '"SAVE_TOKEN/qa1"' is not assignable to type '"SAVE_TOKEN/notqa1"'.

Experiment with it on the TypeScript playground


There are several well-known open proposals/requests such as Regex-validated string type: TypeScript#6579 and TypeScript#12754. This includes a specific mention regarding this use case, but as of version 3.5.1, the answer remains negative.

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

Combining Interfaces in Typescript: Utilizing Union Types with a Base and Extended Interface

I'm facing an issue with the following code snippet interface BaseA { a: number; } interface SpecialA extends BaseA { b: number; } type A = BaseA | SpecialA const a = { a: 5, b: 5 } as A console.log(a.b) Even though I thought the code was ...

Testing the automation processes of a React or Node project

I am currently working on a project developed using React, Node.js, and MongoDB. I am looking to create an automation test that will automatically fill in either the login or register form. If anyone has any ideas or suggestions, please share them with m ...

Make sure to call the loader function in React Router only when there are path params present

I'm currently implementing the new React Router, utilizing loader functions to fetch data based on the loaded element. My goal is to have certain APIs called regardless of the route, with additional APIs triggered for specific routes. However, I&apos ...

Finding the key type in an interface

Here is a challenge... This is the code snippet from titleBarContainer.tsx: function TitleBarContainer() { const systemData = useSelector((state: RootState) => state.counter.systemData) const dispatch = useDispatch() const onChangeSystemDa ...

What is the proper method for utilizing an object as a dependency when using useEffect?

Currently, I am in the process of developing a react hook that takes in a query object. export function useMyQuery(query: QueryObjectType) { React.useEffect(executeQuery, [ query ]); // ... } Unfortunately, whenever my hook is called during a re- ...

Generating a type definition from a JavaScript file

Looking to convert a .js file to a d.ts file, I've noticed that most resources on this topic are from 2 years ago How do you produce a .d.ts "typings" definition file from an existing JavaScript library? My question is, after 2 years, is there a simp ...

The jquery methods might encounter an issue with an undefined object

I have been attempting to implement a function that triggers when the user reaches the bottom of the window, but TypeScript is flagging errors and mentioning potential undefined objects related to window.scrollTop(), height(), and document.height(). Even ...

Implement a call feature using ReactJS

My service method involves making a PUT call to an API with an ID parameter. However, I am facing issues with hitting the .put URL. Can someone please verify if this is the correct approach? ENDPOINTS = { SAMPLE: "/sample", }; Below is my ...

Transferring functionality from a child component to a parent component

I have a Base Component called ListComponent and a ParentComponent named Businesses2ListComponent. The concept is to have multiple types of Lists with tables that all stem from the ListComponent. This requires passing the correct service accordingly. In t ...

Exploring Angular Testing with SpyOn

Apologies for my inexperience with Angular, but I am struggling with using spyOn in a unit test. In my unit test, there is a method on the component that calls service1, which in turn calls another service2. However, when I try to spyOn service1 in order ...

Is there a way to retrieve the value of bindings in the component controller using Angular 1.5 and Typescript?

In my quest to develop a versatile left-hand menu component that can dynamically display different menu structures based on input strings, I stumbled upon an interesting challenge. By binding a string to the <left-hand-menu-component> element like so ...

Is it possible for transclusion to display content from external sources using *ngIf and <ng-content>?

In my Angular4 Project, I have come across this snippet of code: <div class="divider"></div> <ng-content select=".nav-toggle"></ng-content> Now, I am trying to figure out a way to display the divider only when there is content pr ...

What is preventing me from running UNIT Tests in VSCode when I have both 2 windows and 2 different projects open simultaneously?

I have taken on a new project that involves working with existing unit tests. While I recently completed a course on Angular testing, I am still struggling to make the tests run smoothly. To aid in my task, I created a project filled with basic examples f ...

Create interfaces for a TypeScript library that is available on npm for export

I have a project in TypeScript that I am packaging as a library to be used by both JavaScript and TypeScript projects. After compiling, I upload the .js and .d.ts files to npm. The main.ts file exports the following: interface MyInterface{ // ... } clas ...

Move on to the following iteration within a (Typescript) .forEach loop by using setTimeout

Within my array, I have a list of image URLs that I need to update the src attribute of an img tag every 10 seconds. To achieve this, I am using a forEach loop which includes a setTimeout function that calls a DOM manipulation function (replaceImage) as sh ...

Having trouble adding the Vonage Client SDK to my preact (vite) project

I am currently working on a Preact project with Vite, but I encountered an issue when trying to use the nexmo-client SDK from Vonage. Importing it using the ES method caused my project to break. // app.tsx import NexmoClient from 'nexmo-client'; ...

Potential absence of the object has been detected after performing object verification

I encountered an issue with the following error message: Object is possibly 'undefined'.ts(2532) This is what my configuration looks like: export interface IDataColumns { name: string; label: string; display: string; empty: boolean; fi ...

Angular's counterpart to IWebProxy

When using C#, I am able to: public static IWebProxy GetWebProxy() { var proxyUrl = Environment.GetEnvironmentVariable("HTTPS_PROXY"); if (!string.IsNullOrEmpty(proxyUrl)) { var proxy = new WebProxy { Address = new Ur ...

Tips for effectively typing a collection of React wrappers in TypeScript

I encountered a situation in my team's application where we need the ability to dynamically compose component wrappers (HOCs) without prior knowledge of all the wrapper interfaces. This is mostly needed for swapping out context providers when renderin ...

Deciphering the .vimrc setup for tooltips and symbols in TypeScript

Currently, I have integrated the Tsuquyomi plugin for my typescript development in Vim. The documentation mentions tooltips for symbols under the cursor, which are working fine. The issue arises as I am using terminal-based Vim, and even if I were using a ...