如何在Typescript中使用ES6代理?

如何在Typescript中使用ES6代理?,typescript,Typescript,我想尝试一些关于代理的东西,但我很难让最简单的表单运行 我有以下代码 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.t

我想尝试一些关于代理的东西,但我很难让最简单的表单运行

我有以下代码

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

我最近发现的是

当您使用const关键字声明局部变量并用文字值初始化它时,TypeScript将推断该变量的文字类型(从)

这也可以帮助你-


您并没有声明文字常量,但也可能发生类似的情况。我建议声明一个接口来“支持”索引。

这是因为
键定义为
PropertyKey
。这意味着它可能是
string | number | symbol
,它与只有一个键
x
的对象不同。这并不是真正的类型错误-TS不能静态地确保不会使用
x
以外的其他东西调用对象,并假设可能的
值的范围更广。解决此问题的一个方法是确保TypeScript确实是myObj的
键,因为您自己已经在进行运行时检查:

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

感谢@Rafal2228解释问题并提出解决方案。为了完整起见,我想发布我现在是如何修复它的。(带护字板)

const hasKey=(obj:T,k:keyof any):k是keyof T=>
obj中的k;
常数myObj={
x:'你好',
};
const p=新代理(myObj{
get:(目标,关键点)=>{
return hasKey(target,key)-target[key]+'World!':'nope';
},
});
控制台日志(p.x);

TS可以推断一切,您已经要求它不要通过在编译器选项中设置noImplicitAny来推断,因此当您声明参数
target
时,您需要为其指定一个类型。您的解决方案可行,但TS不应该已经确定目标中的
键是否只使用了有效键?这可能与,但不幸的是,TypeScript目前无法做到这一点。
return key in target ? target[key as keyof typeof target] + ' World!' : 'nope';
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);