What is the best way to detect object changes in typescript?

Having an object and the desire to listen for changes in order to execute certain actions, my initial approach in ES6 would have been:

let members = {};
let targetProxy = new Proxy(members, {
    set: function (members, key, value) {
        console.log(key + " set to " + value);
        members[key] = value;
        return true;
    }
});

After converting to TypeScript:

const members = {};
let targetProxy: any = new Proxy(members, {
    set: function (members: any, key: string, value: string) {
        console.log(`${key} set to ${value}`);
        members[key] = value;
        return true;
    }
});

However, encountering an error message from the linter:

[ts] Cannot find name 'Proxy'.

The terminal displays the following output:

https://i.sstatic.net/FwkzD.png

Despite conducting extensive research, I am unable to troubleshoot the issue.

In an attempt to resolve it, I modified my module parameter to ES6 instead of commonjs, but no changes were observed. Full output can be seen below:

https://i.sstatic.net/2REIG.png

Furthermore, here is a snippet from my package.json configuration:

{
  "compilerOptions": {
    "module": "ES6",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "*": ["node_modules/*"]
    }
  },
  "include": [
    "src/**/*"
  ]
}

Answer №1

For your project to function correctly, ensure that the TypeScript compiler options are set to target ES2015 or a newer version (documentation). The command-line option should be --target "ES2015" (or "ES2016", etc., or "ESNext" for the latest proposed features).


Additional information: The set method captures property value assignments in the conventional manner but does not do so when using Object.defineProperty:

const members = {};
let targetProxy = new Proxy(members, {
    set: function(members, key, value) {
        console.log(`${key} set to ${value}`);
        members[key] = value;
        return true;
    }
});
console.log("---- Notice no set trap fired:");
console.log(`targetProxy.foo: ${targetProxy.foo}`);
Object.defineProperty(targetProxy, "foo", {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true
});
console.log(`targetProxy.foo: ${targetProxy.foo}`);
Object.defineProperty(targetProxy, "foo", {
  value: 2,
  writable: true,
  configurable: true,
  enumerable: true
});
console.log(`targetProxy.foo: ${targetProxy.foo}`);
console.log("---- But it's fired for simple assignment:");
console.log(`targetProxy.bar: ${targetProxy.bar}`);
targetProxy.bar = 1;
console.log(`targetProxy.bar: ${targetProxy.bar}`);
targetProxy.bar = 2;
console.log(`targetProxy.bar: ${targetProxy.bar}`);
.as-console-wrapper {
  max-height: 100% !important;
}

In addition, you need a defineProperty trap for this functionality. (Note that both set and defineProperty will be activated when setting a data property, provided that set allows the operation to proceed.)

(Please note that other changes like property deletions, modifications to the prototype, etc., are not captured by these traps.)


Another point to consider: The key parameter in the set trap is of type string | Symbol, not just string.

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

The journey of communication: uncovering the essence of @input between parent and

I'm diving into Angular and currently working on the @Input phase. Within my main app, there's a child component. Inside app.component.ts, I've declared a test variable that I wish to pass from app.component.ts to child.component.ts. // ap ...

What is the recommended return type in Typescript for a component that returns a Material-UI TableContainer?

My component is generating a Material-UI Table wrapped inside a TableContainer const DataReleaseChart = (): React.FC<?> => { return ( <TableContainer sx={{ display: 'grid', rowGap: 7, }} > ...

Creating a setup with Angular 2+ coupled with Webpack and a Nodejs

I have successfully configured Angular2+webpack along with NodeJs for the backend. Here is a basic setup overview: webpack.config.js: var webpack = require('webpack') var HtmlWebpackPlugin = require('html-webpack-plugin') var Extract ...

Unlocking $refs with the Composition API in Vue3 - A step-by-step guide

I am currently exploring how to access $refs in Vue 3 using the Composition API. In my template, I have two child components and I specifically need to obtain a reference to one of them: <template> <comp-foo /> <comp-bar ref="ta ...

Limit the field type depending on the value of another field

Consider the following scenario: type ActionType = 'action1' | 'action2' | 'action3'; interface Action { type: ActionType; value?: number | Date; } Is there a method in typescript to enforce restriction ...

Filter and transfer data from one Angular array to another

As a newcomer to Angular, I am working with an array of events containing multiple arguments. My goal is to filter these events and separate them into two new arrays: upcoming events and past events. Below is a snippet of the TypeScript code I am using: a ...

How to easily deactivate an input field within a MatFormField in Angular

I've come across similar questions on this topic, but none of the solutions seem to work for me as they rely on either AngularJS or JQuery. Within Angular 5, my goal is to disable the <input> within a <mat-form-field>: test.component.h ...

Utilizing NGRX reducers with a common state object

Looking for a solution with two reducers: export function reducer1(state: State = initialState,: Actions1.Actions1); export function reducer2(state: State = initialState,: Actions2.Actions1); What I want is for both reducers to affect the same state objec ...

Extract objects from a nested array using a specific identifier

In order to obtain data from a nested array of objects using a specific ID, I am facing challenges. My goal is to retrieve this data so that I can utilize it in Angular Gridster 2. Although I have attempted using array.filter, I have struggled to achieve t ...

How can TypeScript rules be incorporated into a Next.js project without compromising next/core-web-vitals?

In my current NextJS project which is in typescript, I have the following configuration in my .eslintrc.json: { "extends": "next/core-web-vitals" } Now, I want to include additional typescript rules, such as enforcing the rule of n ...

Compiling with tsc --build compared to tsc --project

I'm currently working on converting a subproject to TypeScript within my monorepo. Within my npm scripts, I initially had: "build-proj1":"tsc --build ./proj1/tsconfig.json" Although it did work, I noticed that the process was unus ...

Steps for injecting strings directly into Angular2 EventBindingWould you like to learn how

Is it feasible to achieve something similar to this? <li><a href="#" target="_blank" (click)="createComponent(MYSTRINGHERE)">Departamentos</a></li> ...

React.js - Issue with table not being redrawn after data filtering

I am encountering an issue with my table in Next.js where the text input is not triggering a redraw. The expected behavior is to update the table with a single search result, but currently only the top row reflects the search result. Below is my useEffect ...

Having difficulties generating ngc and tsc AOT ES5 compatible code

I've explored various options before seeking help here. I have an angular2 library that has been AOT compiled using ngc. Currently, I am not using webpack and solely relying on plain npm scripts. Below is the tsconfig file being utilized: { "comp ...

Angular 4 - Sum all values within a nested array of a data model

I am working with an array of Models where each object contains another array of Models. My goal is to calculate the sum of all the number variables from the nested arrays using the code snippet below. Model TimesheetLogged.ts export interface Timesheet ...

choose a distinct value for every record in the table

My goal is to only change the admin status for the selected row, as shown in the images and code snippets below. When selecting 'in-progress' for the first row, I want it to update only that row's status without affecting the others. <td ...

Trouble with Nextjs link not functioning properly with a URL object when incorporating element id into the pathname

Recently I added translations to my website, which means I now need to use a URL object when creating links. Everything has been going smoothly with this change except for one issue: when I try to click a link that points to /#contact. When simply using h ...

issue TS2322: The function returns a type of '() => string' which cannot be assigned to type 'string

I have recently started learning Angular 6. Below is the code I am currently working on: export class DateComponent implements OnInit { currentDate: string = new Date().toDateString; constructor() { } ngOnInit() { } } However, I am encounterin ...

What is the best way to send serverside parameters from ASP.Core to React?

After setting up a React/Typescript project using dotnet new "ASP.NET Core with React.js", I encountered the following setup in my index.cshtml: <div id="react-app"></div> @section scripts { <script src="~/dist/main.js" asp-append-versi ...

Leveraging Renderer in Angular 4

Understanding the importance of using a renderer instead of directly manipulating the DOM in Angular2 projects, I have gone through multiple uninstallations, cache clearings, and re-installations of Node, Typescript, and Angular-CLI. Despite these efforts, ...