How to customize properties in TypeScript
Asked Answered
C

3

20

How do I get TypeScript to emit property definitions such as:

Object.defineProperties(this, {
    view: {
        value: view,
        enumerable: false,
        writable: false,
        configurable: false
    },
});
Carnation answered 2/10, 2012 at 18:40 Comment(0)
C
13

I was looking for exactly the same thing when I stumbled upon TypeScript Handbook: Decorators. In "Method Decorators" paragraph they define @enumerable decorator factory, which looks like this (I'm simply copy-pasting from there):

function enumerable(value: boolean) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        descriptor.enumerable = value;
    };
}

and they use it like this:

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }

    @enumerable(false)
    greet() {
        return "Hello, " + this.greeting;
    }
}

So another way of addressing it, is through usage of decorators.

PS: This feature requires experimentalDecorators flag to be passed to tscor set in tsconfig.json.

Congratulant answered 27/2, 2017 at 16:39 Comment(0)
S
11

You can use get and set in TypeScript, which compile into Object.defineProperties.

This is an ECMAScript 5 feature, so you can't use it if you are targeting ES3 (the default for the compiler). If you are happy to target ES5, add --target ES5 to your command.

TypeScript:

class MyClass {
    private view;
    get View() { return this.view; }
    set View(value) { this.view = value }
}

Compiles to:

var MyClass = (function () {
    function MyClass() { }
    Object.defineProperty(MyClass.prototype, "View", {
        get: function () {
            return this.view;
        },
        set: function (value) {
            this.view = value;
        },
        enumerable: true,
        configurable: true
    });
    return MyClass;
})();

But if you want full control of setting enumerable and configurable - you could still use the raw Object.defineProperties code.

Soever answered 4/10, 2012 at 21:42 Comment(1)
Ok... but how do you handle something like: describe('MyComponent', () => { beforeAll(() => { Object.defineProperty(window, 'matchMedia', { value: jest.fn(() => { return {matches: true}; }) }); }); });Senator
L
1

This isn't currently supported if you want all the properties to be emitted like that. I'd recommend filing an issue at the CodePlex site with details about what your use case and requirements are.

If you do compile with --target ES5, you can have something like this:

class n {
    get foo() { return 3; }
    bar() { return 5; }
}

Which produces this code:

var n = (function () {
    function n() { }
    Object.defineProperty(n.prototype, "foo", {
        get: function () {
            return 3;
        },
        enumerable: true,
        configurable: true
    });
    n.prototype.bar = function () {
        return 5;
    };
    return n;
})();
Lifework answered 2/10, 2012 at 18:43 Comment(1)
yeah, i'm looking for a way to customize the 'enumerable', 'configurable' and 'writable' attributes to match my existing code.Carnation

© 2022 - 2024 — McMap. All rights reserved.