如何使用打字稿收听对象更改?

时间:2018-11-16 10:32:18

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

我有一个对象,我想听更改以执行一些操作,在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;
    }
});

但是短绒棉给我看了这个错误消息

[ts] Cannot find name 'Proxy'.

终端输出:

tsc output

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

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

Complete output error message typescript Proxy module

和我的package.json

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

1 个答案:

答案 0 :(得分:3)

您的项目需要将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陷阱。 (请注意,假设set允许进行操作,则在设置数据属性时将同时触发definePropertyset。)

(它也不会捕获其他更改,例如删除属性,更改原型等)


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