【问题标题】:Typescript: Using array notation to get items from class打字稿:使用数组表示法从类中获取项目
【发布时间】:2017-09-12 21:32:25
【问题描述】:

我有一个名为Candles 的课程和一个名为Candle 的课程。 Candles 有一个属性list,其中包含Candle 的数组。

class Candles
{
  public list: Array<Candle>;
}

class Candle
{
  public date: number;
  public high: number;
  public low: number;
  public open: number;
  public close: number;
  public volume: number;
}

我希望 list 使用 Candles 类进行封装。例如,

const candles = new Candles();
candles[3] === candles.list[3];

我想让candles[3]返回candles.list[3]

我也想用地图。示例:

candles.map(function(candle: Candle) {
    console.log(candle.high);
});

【问题讨论】:

    标签: typescript typescript2.4


    【解决方案1】:

    您可以使用 ES6 Proxy 拦截和转发对内部列表的调用:

    class Candles {
      public list: Candle[] = [];
    
      constructor() {
        return new Proxy(this, {
          get(target, propertyKey) {
            console.log('getting ', propertyKey);
            if (propertyKey in target) {
              console.log('own property');
              return target[propertyKey]
            }
    
            console.log('forward to inner list');
            const property = target.list[propertyKey];
            if (typeof property === "function") {
              return property.bind(target.list);
            }
    
            return property;
          }
        });
      }
    }
    

    要通知编译器Candles 可以用作Array,请添加以下定义:

    interface Candles extends Array<Candle> { }
    

    现在所有的数组好东西(例如pushforeachmap...)都可以应用于Candles

    const candles = new Candles();
    candles.push({ low: 1 } as Candle);
    
    console.log(candles[0] === candles.list[0]); //true
    candles.forEach(c => console.log(c));
    

    Demo 在操场上。

    【讨论】:

      【解决方案2】:

      您无法更改 Typescript 中索引操作的行为,因为 Javascript 也不支持这一点。您可以做的是创建一个扩展标准数组的类型,如question

      中所述

      【讨论】:

        【解决方案3】:

        您想要的是运算符重载。 Typescript 不支持它。

        您可以在 github 问题线程中了解更多关于为什么会出现这种情况的原因: https://github.com/Microsoft/TypeScript/issues/2319 https://github.com/Microsoft/TypeScript/issues/5407

        【讨论】:

          【解决方案4】:

          这就是我所做的:

          class Candles extends Array<Candle>
          {
            constructor(candles: Array<Candle.Data>) {
              super(...candles.map((candle) => new Candle(candle as Candle.Data)));
              Object.setPrototypeOf(Candles, Object.assign(Array.prototype, Candles.prototype));
            }
          }
          

          我摆脱了list,只是扩展了Array&lt;Candle&gt;。我还添加了Object.setPrototypeOf(Candles, Object.assign(Array.prototype, Candles.prototype)); 以使用Array 方法和Candles 的方法

          【讨论】:

            猜你喜欢
            • 2021-09-01
            • 2022-01-23
            • 2022-11-03
            • 2020-06-20
            • 2019-03-12
            • 2021-12-08
            • 2022-01-05
            • 2018-08-31
            • 2018-09-11
            相关资源
            最近更新 更多