打字稿中的索引器

时间:2017-11-27 10:59:31

标签: c# typescript

我有一个c#Class

    class BaseModel
    {  
       private Dictionary<string, string> _attr;

       public string this[string propName]
       {
           get
           {
               string strReturnValue = string.Empty;
               if (this._attr.ContainsKey(propName))   
                  strReturnValue = this._attr[propName];
               return strReturnValue;
           }
           set
           {
              if (!this._attr.ContainsKey(propName))
                 this._attr.Add(propName, value);
              else
                  this._attr[propName] = value;
              // Doing something here
           }
        }

        public BaseModel(BaseModel aParent)
        {
            this._attr = new Dictionary<string, string>();
        }
    }

基本上我想在通过索引器属性设置字典时执行一些代码,我找不到在typescript中执行此操作的方法。任何人都可以帮我解决这个问题。

1 个答案:

答案 0 :(得分:1)

如果您使用的是es2015,则可以使用buit-in Proxy类。这将允许您拦截任何索引集/ get:

class BaseModel
{
    attr : { [propName: string] : string} = {};
    getValue(name: string) : string {
        return this.attr[name] || ""
    }
    setValue(name: string, value: string) {
        this.attr[name] = value;
    }
}

var p = new Proxy(new BaseModel(), { 
    get: (target, name)=> target.getValue(<string>name),
    set: (target, name, value)=> {
        target.setValue(<string>name, value)
        return true;
    }
});

console.log(p["unset"]); //Output ""
p["test"] = "set"
console.log(p["test"]); //Output set

注意必须通过代理完成对该对象的所有访问,并且因为您无法扩展Proxya limitation of JS),所以您无法真正使用它基类(顾名思义你可能想要)。您可以将构造函数设为私有,并使用静态create方法确保使用代理创建所有对象,这将使此解决方案可用:

class BaseModel
{
    protected constructor (){

    }
    attr : { [propName: string] : string} = {};
    getValue(name: string) : string {
        return this.attr[name] || ""
    }
    setValue(name: string, value: string) {
        this.attr[name] = value;
    }
    public static wrap<T extends BaseModel>(value: T): T {
        return new Proxy(value, { 
            get: (target, name)=> target.getValue(<string>name),
            set: (target, name, value)=> {
                target.setValue(<string>name, value)
                return true;
            }
        });
    }
}
class Derived extends BaseModel {
    protected constructor (){
        super();    
    }
    public static createDerived(): Derived {
        return BaseModel.wrap(new Derived());
    }
}
var p =  Derived.createDerived();
console.log(p["unset"]); //Output ""
p["test"] = "set"
console.log(p["test"]); //Output set