如何在Typescript中使用ES6代理?

时间:2019-12-18 10:29:24

标签: typescript

我想尝试一些有关Proxies的事情,但是我很难使最简单的表单运行。

我有以下代码

const myObj = {
  x: 'Hello',
};

const p = new Proxy(myObj, {
  get: (target, key) => {
    return key in target ? target[key] + ' World!' : 'nope';
  },
});

console.log(p.x);

我得到以下错误,但是我不知道为什么以及如何解决它:

index.ts:7:28 - error TS7053: Element implicitly has an 'any' type because expression of type 'string | number | symbol' can't be used to index type '{ x: string; }'.
  No index signature with a parameter of type 'string' was found on type '{ x: string; }'.

7     return key in target ? target[key] + ' World!' : 'nope';
                             ~~~~~~~~~~~

Found 1 error.

我认为TS应该能够推断一切。我在这里想念什么?

3 个答案:

答案 0 :(得分:0)

我最近发现的是

  

当您使用const关键字声明局部变量并使用文字值对其进行初始化时,TypeScript会推断出该变量的文字类型(来自https://mariusschulz.com/blog/literal-type-widening-in-typescript

const numericLiteral = 42;     // Type 42

请参见https://www.typescriptlang.org/docs/handbook/variable-declarations.htmlhttps://mariusschulz.com/blog/literal-type-widening-in-typescripthttps://blog.logrocket.com/const-assertions-are-the-killer-new-typescript-feature-b73451f35802/

这也可能对您有帮助-https://medium.com/@SylvainPV/type-safety-in-javascript-using-es6-proxies-eee8fbbbd600

您不是在声明文字常量,但是类似的事情也可能发生。而且我建议声明一个接口以“支持”索引。

答案 1 :(得分:0)

这是因为key被定义为PropertyKey。这意味着它可能是string | number | symbol,它与您的对象只有一个密钥x是不同的索引签名。类型并不是真正的错误-TS无法静态确定不会用x以外的对象来调用您的对象,并且假设可能的key值的范围更广。解决此问题的一种方法是,确保TypeScript确实是keyof myObj,因为您已经在自己进行运行时检查了:

return key in target ? target[key as keyof typeof target] + ' World!' : 'nope';

答案 2 :(得分:0)

@ Rafal2228,以解释问题并提出解决方法。为了完整起见,我想发布我现在如何解决的问题。 (使用TypeGuard)

const hasKey = <T extends object>(obj: T, k: keyof any): k is keyof T =>
  k in obj;

const myObj = {
  x: 'Hello',
};

const p = new Proxy(myObj, {
  get: (target, key) => {
    return hasKey(target, key) ? target[key] + ' World!' : 'nope';
  },
});

console.log(p.x);