Creating dynamic properties in TypeScript for Proxy objects

Looking to create a JavaScript Proxy that enables access to arbitrary properties. For example, an object that assigns each property its own name:

const proxy = new Proxy({}, {
  get(target, property) {
    return prop;
  }
});
proxy.foo // results in "foo"
// Property 'foo' does not exist on type '{}'.ts(2339)

I understand that TypeScript may not automatically recognize the existence of proxy.foo, but I am seeking a way to specify a type so that it knows the property exists and also the value type depends on the specific property name.

The mapped type below prevents TypeScript from flagging the property as non-existent, however it infers the type as string instead of the more precise "foo":

const proxy = new Proxy<{ [T in string]: T }>({}, {
  get(target, prop) {
    return prop;
  }
});
proxy.foo // inferred as `string` instead of `"foo"`

I have also attempted using { readonly [T in string]: T }.

Interestingly,

({} as { [T in "foo" | "bar"]: T }).foo
will be recognized as `"foo"`, however, I cannot list out all potential keys.

Is there a method to make TypeScript utilize the exact key within the value's type in a mapped type, or another technique to precisely type a Proxy with dynamic properties?

Answer №1

One potential solution could involve creating a helper type that generates an object with identical key-value pairs initially.

// Generate object with same key and value types
type Duplicate<Keys extends string> = { [K in Keys]: K };

type FooBar = Duplicate<'foo' | 'bar'>

const foobar = new Proxy<FooBar>({} as FooBar, {...})
foobar.bar // will be recognized as 'bar'

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

React Native bottom tab navigator not changing between tabs

Hi, I'm new to React Native and I think I might have a structural issue because I can't figure out what I'm doing wrong. I'm trying to create 4 tabs, but when I click on each tab, it doesn't take me to the next page. Nothing happe ...

Cypress eliminating the "X-CSRFToken" header

There seems to be an issue with the Cypress test runner where it is removing X-CSRFToken from the request header, leading to a 403 Forbidden error. I have compared the headers between a manual run and a Cypress test run, and you can see the difference in t ...

When you extend the BaseRequestOptions, the injected dependency becomes unspecified

Implementing a custom feature, I have chosen to extend BaseRequestOptions in Angular2 to incorporate headers for every request. Additionally, I have introduced a Config class that offers key/value pairs specific to the domain, which must be injected into m ...

Tips for updating the value.replace function for the "oninput" attribute within Angular 7

I need to modify an input based on a value from a TypeScript variable in the oninput attribute. This modification should only apply to English characters. In my HTML file: <input class="form-control" oninput="value=value.replace(r ...

Is it possible to globally modify the component reference <dropdown-component> name in Angular during runtime in a dynamic manner?

I am currently working on an application that utilizes a component called "dropdown-component" throughout its pages. However, due to specific business requirements, I have been tasked with replacing "dropdown-component" with "custom-dropdown-component". Un ...

How can data be transferred from a parent to a child component in Angular?

I'm facing an issue trying to pass the selected value from a dropdownlist in a user interface. I have a parent component (app.component.html) and a child component (hello.component.html & hello.component.ts). My goal is to transfer the option val ...

Display the list of cities associated with the country chosen in the form

I am currently working with the repository found at https://github.com/country-regions/country-region-data/blob/master/data.js to create a mapping of countries and their related cities. I'm seeking guidance on how to achieve this task effectively. My ...

Using ts-node throws an error when checking if window is equal to "undefined" using typeof

I encountered an issue with my code where I used typeof window == "undefined" to check for a browser environment. When running this code with ts-node, I ran into the following error: typings/Console.ts:36:10 - error TS2304: Cannot find name 'window&a ...

Struggling to get Tailwind typography to play nice with a multi-column React application shell

I'm currently working on a React application with TypeScript and trying to integrate one of Tailwind's multi-column application shells (this specific one). I want to render some HTML content using Tailwind Typography by utilizing the prose class. ...

I am unable to retrieve the values from a manually created JavaScript list using querySelectorAll()

const myList = document.createElement("div"); myList.setAttribute('id', 'name'); const list1 = document.createElement("ul"); const item1 = document.createElement("li"); let value1 = document.createTe ...

Concise way to add or insert an element into an array, at a specific property of an object

I am working with an object of the ObjectOfArrays type: type ObjectOfArrays = { [id: string]: Array<string> }; Throughout my code, I need to add strings to the correct array based on the id. Currently, I am using the following approach: if (id i ...

When attempting to add a variable using the next() function, I encountered an error with the BehaviorSubject. The error message displayed was "this.count.next is not a function"

In my Angular service, there is a variable called count that I need to monitor for updates. Whenever this count variable is updated, I want to assign its new value to another variable in a separate component. import {BehaviorSubject} from "rxjs/BehaviorSu ...

Having trouble decoding a cookie received from a React.js front-end on an Express server

When using React js for my front end, I decided to set a cookie using the react-cookie package. After confirming that the request cookie is successfully being set, I moved on to configure the Express server with the cookie parser middleware. app.use(cookie ...

Angular 4: Transform a string into an array containing multiple objects

Recently, I received an API response that looks like this: { "status": "success", "code": 0, "message": "version list", "payload" : "[{\"code\":\"AB\",\"short\":\"AB\",\"name\":\"Alberta&b ...

The issue arising from utilizing the export class function in Angular 8

Hey there! I'm working on an Angular application and just getting started with it. My current version is Angular 8, and I've encountered an issue that I need help with. In my project, I have a shared model named "Client" which is defined in a fi ...

The @Column('decimal') decorator in TypeOrm with Postgres and NestJs is displaying a string instead of a decimal value

When I have columns with type decimal and I am using query builder for aggregation, I face an issue where the decimal values are returned as strings after executing the query. I am looking for a way to globally set my project to recognize decimal numbers ...

Subclasses do not have the ability to invoke methods and properties

My intention is to utilize different low-level implementations in various environments while abstracting the specific details from higher-level modules. The expectation is to have a standard way of using the class on the outer layer. The buildEnv variabl ...

Unleashing the power of await with fetch in post/get requests

My current code has a functionality that works, but I'm not satisfied with using it. await new Promise(resolve => setTimeout(resolve, 10000)); I want to modify my code so that the second call waits for the result of the first call. If I remove the ...

Is there a specific type of function missing in Typescript?

I am facing a challenge in converting an existing JavaScript code to Typescript. The original javascript code is as follows: object.getsomething( function(err, result) { // async }); I am confused about how to properly type the parameter "function(er ...

What is the process for attaching a function to an object?

Here is the complete code: export interface IButton { click: Function; settings?: IButtonSettings; } abstract class Button implements IButton { click() {} } class ButtonReset extends Button { super() } The component looks like this: expor ...