【问题标题】:Typescript :: namespacing functions within a class?Typescript :: 类中的命名空间函数?
【发布时间】:2016-11-24 07:55:37
【问题描述】:

假设这样一个简单的类:

class Simple {
  private _transactions: [];
  makeTransaction() { ... }
  revertTransaction() { ... }
  // some other methods as well...
}

let obj = new Simple();
obj.makeTransaction(...);
obj.makeTransaction(...);
obj.revertTransaction(...);

现在,我想公开更多与报告相关的方法,我想将它们分组如下:

obj.reports.allTransactions();
obj.reports.reveretedTransactions();
obj.reports.clearedTransactions();

这些方法将使用 Simple 类本身的私有变量来返回一些报告。

我使用以下方法来实现这一点:

class Simple {
  private _test = () => { return this._transaction }
  reports = {
    getAll: this._test
  }
}

这可行,但它有几个缺点:

  1. 它迫使我将所有必需的函数声明为类本身的一部分,然后再次在 reports 对象中引用它们。
  2. Typescript 告诉我obj.reports.getAll 是一个属性,尽管我也可以将它作为函数调用。即便如此,我还是没有得到正确的函数签名提示。
  3. 它迫使我不必要地使用箭头函数(闭包)。

有没有更好的方法来做同样的事情?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以为reports 对象创建一个类:

    class Reports {
        private _transactions: any[];
    
        constructor(transactions: any[]) {
            this._transactions = transactions;
        }
    
        getAll() {
            return this._transactions;
        }
    }
    
    class Simple {
        private _transactions: any[];
        public reports: Reports;
    
        constructor() {
            this._transactions = [];
            this.reports = new Reports(this._transactions);
        }
    
        makeTransaction() {}
        revertTransaction() { }
    }
    

    (code in playground)


    编辑

    您也可以将reports 公开为一个类型:

    interface Reports {
        getAll(): any[];
    }
    
    class Simple {
        private _transactions: any[];
        public reports: Reports;
    
        constructor() {
            this._transactions = [];
            this.reports = {
                getAll: () => {
                    return this._transactions;
                }
            }
        }
    
        makeTransaction() {}
        revertTransaction() { }
    }
    

    (code in playground)


    第二次编辑

    另一种选择是将报告分成不同的类,但将 Simple 实例作为其成员,并将该实例的所有成员设为公共。
    如果你然后将Simple 变成一个界面,你可以隐藏那些公共成员:

    class Reports {
        private _simple: SimpleImpl;
    
        constructor(simple: SimpleImpl) {
            this._simple = simple;
        }
    
        getAll() {
            return this._simple.transactions;
        }
    }
    
    interface Simple {
        makeTransaction();
        revertTransaction();
    }
    
    class SimpleImpl implements Simple {
        public transactions: any[];
        public reports: Reports;
    
        constructor() {
            this.transactions = [];
            this.reports = new Reports(this);
        }
    
        makeTransaction() {}
        revertTransaction() {}
    }
    

    (code in playground)

    如果只公开Reports 类和Simple 接口,则公共成员仅对Reports 的实例可见。

    【讨论】:

    • Hmm.. 虽然这确实有效,但它在两个类之间拆分实现.. 我给出的示例是一个精简的.. 在我的实际用例中,我有大约 10 个私有字段及其参考不是恒定的(clear()=> this._list = [])..但是如果没有其他方法可以去..我会接受这个答案..=)
    • You can also expose reports as a type.. 这个!是我需要的!非常感谢队友..这工作得很好..不需要单独的类共享数据..闭包维护this参考..太棒了!
    • 如果这个类变得太大和/或Reports 中的逻辑变得太长,那么最好将它分成不同的类(避免“难闻的气味”)。我用一种很好的方式更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 2011-03-29
    • 2018-06-23
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 2012-06-11
    相关资源
    最近更新 更多