首页 > 解决方案 > 打字稿创建索引签名以代理对子对象的访问

问题描述

我对 Typescript 很陌生,如果这不是一个好问题,我深表歉意。

我有一个对象(A),它包装了另一个对象(B),并提供了一些作用于 B 的方法。我试图代理对 A 的访问,以便返回 B 上该键的值。一个人为的代码示例如下:


type AType = {
  state: StateType
  doubleSomeVal(): number;
} & StateType

type StateType = {
   someVal: number;
}


type StateTypeKey = "someVal"

class A implements AType {
    state: StateType;

    doubleSomeVal() {
      return this.state.someVal * 2;
    }

    constructor(state: StateType) {
      this.state = state;
    }

    static create(state: StateType) {
      return new Proxy(new A(state), { 
        get(target: A, key: StateTypeKey) {
          return target.state[key] || target[key];
        }
     });
    }
} 

但是随后 TS 抱怨,因为它看不到我的类 A 具有属于它的 StateType 属性 - 这是有道理的,但如果可能的话,我想解决它。

标签: typescript

解决方案


所以我认为你实际上不想A实现AType,因为它只是它的输出A.create()。所以我会把你的A班级改成这样:

class A {
  state: StateType;

  doubleSomeVal() {
    return this.state.someVal * 2;
  }

  constructor(state: StateType) {
    this.state = state;
  }

  static create(state: StateType) {
    return new Proxy(new A(state) as A & A["state"], {
      get(target, key) {
        return Reflect.has(target.state, key)
          ? Reflect.get(target.state, key)
          : Reflect.get(target, key);
      }
    });
  }
}

请注意,断言的目标Proxy是本质上与 相同。这个断言在某处是必要的,因为编译器不能轻易地验证代理将充当那个交集。我还更改了处理程序的实现,使其对编译器更友好(参数确实是,而且我不喜欢缩小到那里的一些文字联合),并规避. 但基本上是一样的。A & A["state"]ATypegetkeystring | number | symboltarget.state[key]

然后我想你会这样使用它:

const a = A.create({ someVal: 4 });
console.log(a.state); // {someVal: 4}
console.log(a.someVal); // 4
console.log(a.doubleSomeVal()); // 8

编译得很好并给出了所需的输出。好的,希望有帮助。祝你好运!

链接到代码


推荐阅读