You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中创建索引签名实现对子对象的代理访问问题

Hey there! No worries at all—we’ve all stumbled through TypeScript’s proxy and type intersection quirks when starting out. Let’s break down how to fix this issue cleanly.

The Core Problem

Your AType is an intersection of your class’s base functionality plus StateType, so TypeScript expects class A to actually implement all StateType properties directly. But since you’re using a proxy to forward those property accesses to state instead, TypeScript can’t automatically infer that the proxy will handle those missing properties.

Solution 1: Explicit Type Alignment with Proxy

We can split the types to separate what the class actually implements vs. what the proxy exposes, then explicitly tell TypeScript what the proxy returns. Here’s the adjusted code:

// Define the core state type
type StateType = { someVal: number; };

// Define what the class A actually implements (no StateType properties here)
type ABase = {
  state: StateType;
  doubleSomeVal(): number;
};

// The public type we want to expose: core functionality + state properties
type AType = ABase & StateType;

class A implements ABase {
  state: StateType;

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

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

  static create(state: StateType): AType {
    return new Proxy(new A(state), {
      get(target: A, key: keyof AType) {
        // Forward StateType property accesses to target.state
        if (key in target.state) {
          return (target.state as Record<string, unknown>)[key];
        }
        // Fall back to the class's own properties/methods
        return (target as Record<string, unknown>)[key];
      }
    }) as AType; // Assert the proxy matches our desired public type
  }
}

Why This Works:

  • We split AType into ABase (what the class truly implements) and the intersection with StateType (what the proxy exposes). This avoids forcing the class to define properties it doesn’t actually have.
  • The create method explicitly returns AType, and we use a type assertion to tell TypeScript the proxy instance matches this type (since TS can’t infer proxy behavior on its own).
  • The proxy’s get handler checks if the key exists in state first, falling back to the class’s own members if not.

Solution 2: Getters (For Small State Types)

If your StateType has only a few properties, you could define getters directly in the class to avoid proxies entirely:

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

class A implements AType {
  state: StateType;

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

  // Add a getter for each StateType property
  get someVal() {
    return this.state.someVal;
  }

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

This is simpler for small state shapes but doesn’t scale well if StateType has many properties—hence the proxy approach is better for flexibility.

内容的提问来源于stack exchange,提问作者Keir Lavelle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:27:05