如何在 typescript 中使用ES6代理?

ndasle7k  于 2023-02-13  发布在  TypeScript
关注(0)|答案(5)|浏览(211)

我想尝试一些东西周围的代理,但我很难得到最简单的形式运行。
我有下面的代码

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应该能推断出一切,我在这里错过了什么?

nbewdwxp

nbewdwxp1#

这是因为key被定义为PropertyKey。这意味着它可能是string | number | symbol,这是不同于你的对象的索引签名,你的对象只有一个键x。这不是真正的类型错误- TS不能静态地确定你的对象不会被x以外的东西调用,并假设可能的key值的范围更大。一种解决方案是向TypeScript保证它确实是keyof myObj,因为您已经自己做了运行时检查:

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

r9f1avp52#

感谢@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);
rm5edbpk

rm5edbpk3#

我现在用的是

const someProxy = new Proxy(someObj, {
  get(target: typeof someObj, prop: keyof typeof someObj) {
    return target[prop];
  },
});

这将在编写代码期间激活类型检查。
但是我已经厌倦了一遍又一遍的打字。现在正在寻找一个更好的解决方案。

epggiuax

epggiuax4#

可以显式指定key参数的类型:

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

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

console.log(p.x);
gfttwv5a

gfttwv5a5#

我最近发现
当您使用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
你没有声明常量,但是类似的事情也可能发生。我建议声明一个接口来“支持”索引。

相关问题