【问题标题】:How can I listen to object changes using typescript?如何使用打字稿收听对象更改?
【发布时间】:2019-04-19 12:49:06
【问题描述】:

我有一个对象,我想听更改以执行一些操作,在 ES6 中我会这样做:

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

在打字稿中转换

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;
    }
});

但是 linter 向我显示了这个错误信息

[ts] Cannot find name 'Proxy'.

终端输出:

我进行了一些研究,但无法找到问题所在。

按照建议,我将模块参数更改为 ES6 而不是 commonjs,没有任何反应。 下面完成输出

还有我的 package.json

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

【问题讨论】:

标签: typescript ecmascript-6 visual-studio-code


【解决方案1】:

您的项目需要将 TypeScript 编译器选项设置为面向 ES2015 或更高版本 (docs)。命令行选项将是 --target "ES2015"(或 "ES2016" 等,或 "ESNext" 以针对最新提议的功能)。


旁注:set 以正常方式捕获设置属性值,但不是通过 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;
}

为此,您还需要一个defineProperty 陷阱。 (注意setdefineProperty在设置数据属性时都会被触发,假设set允许操作继续进行。)

(它也没有捕捉到其他变化,例如删除属性、更改原型等)


旁注 2:set 陷阱的 key 参数是 string | Symbol,而不仅仅是 string

【讨论】:

  • 我将参数更改为 ES6 但似乎没有任何反应
  • 你为什么用“let”代替“targetProxy”?我认为“const”一定更合适。
  • @DaniloAkou - 我刚刚复制了问题中的代码,您使用了let。回复您的package.json,您设置了module 选项(设置要使用的模块输出格式的样式),而不是我上面提到的target 选项。
猜你喜欢
  • 2019-01-13
  • 2019-01-13
  • 2020-08-09
  • 2020-03-04
  • 2020-04-25
  • 2023-03-07
  • 2016-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多