【问题标题】:Typescript default getter of class propertiesTypescript 类属性的默认获取器
【发布时间】:2018-01-25 03:15:13
【问题描述】:

假设我有一个具有内部私有属性的类:

export class foo {
    private bar_:string;
    private baz_:number;
    constructor() { }

我知道我可以通过为变量编写一个 getter 从 bar 和 baz 获取值。

    get bar():string {
        return this.bar_;
    }
    get baz():number {
        return this.baz_;
    }

这允许我使用以下方式访问数据:

let A:foo = new foo();
console.log(foo.baz);

有没有办法拥有一个简单的通用 getter,所以在使用更结构化的类时,我可以访问任何字段而无需编写单独的 get。

console.log(A.field2);

field2 不是已定义的 getter,但我希望能够在类中执行以下操作:

export class foo {
    private bar_:string;
    private baz_:number;
    private field2_:string;
    constructor() { }

    get X():any {        // X here is some placeholder that could be used, which contains the field name being asked (bar_, baz_, etc.)
        return this.X;       // This would assume that a field is the same name as what was passed.
    }

在 HTML 或其他区域,我可以将值作为 A.bar_ 访问,这将允许我保护私有变量,但无需为每个字段编写 getter 即可获得对其的外部访问。这也可以扩展到更复杂的结构。

【问题讨论】:

    标签: typescript generics getter


    【解决方案1】:

    如果你希望属性是只读的并且你可以在构造函数中设置它们,你可以使用readonly修饰符:

    export class foo {
        constructor(
            public readonly bar:string,
            public readonly baz:number,
            public readonly field2:string) { 
    
        }
    }
    

    如果你只想从 HTML 模板访问属性,你可以使用装饰器来创建 getter,但它们不会出现在类型上:

    function createGetter (target: any, key: string) {
        let propName = key.substr(0, key.length - 1);
        Object.defineProperty(target, propName, {
            get: function() {
                return this[key]
            }
        });
    }
    
    
    export class foo {
        @createGetter private bar_:string;
        @createGetter private baz_:number = 10;
        @createGetter private field2_:string;
        constructor() { }
    }
    

    如果您不介意一些复杂的语法并且只声明属性,您也可以访问 from typescript:

    function withGetters<TProps>() {
        return <TBase>(cls: new () => TBase) : new () => TProps & TBase => {
            return <any>cls;
        };
    }
    class baseFoo {
        @createGetter private bar_:string;
        @createGetter private baz_:number = 10;
        @createGetter private field2_:string;
        constructor()  { }
    }
    export const foo = withGetters<{ 
        readonly bar: string;
        readonly baz: number; 
        readonly field2: string; 
    }>()(baseFoo);
    

    【讨论】:

    • 令人印象深刻。但是为什么let propName = key.substr(0, key.length - 1);
    • @jcairney 这只是问题中使用的约定,字段以_ 结尾,属性已删除_。我花了一段时间才记起来,这是很久以前的事了:)
    猜你喜欢
    • 2022-08-11
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 2017-01-26
    • 2018-04-10
    • 2020-09-08
    • 1970-01-01
    • 2018-12-13
    相关资源
    最近更新 更多