Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property decorator only for a specific property type

I have a property decorator in TypeScript that is only usable on properties of type Array. To enforce this, a TypeError is thrown at runtime if the property type is not Array (using reflect metadata to get property type information):

function ArrayLog(target: any, propertyKey: string) {
    if (Reflect.getMetadata("design:type", target, propertyKey) !== Array) {
        throw new TypeError();
    }

    // ...
}

However, I wouldn't consider this too dev-friendly. How could I make it so that the TypeScript compiler allows using a certain property decorator only on properties with a certain type?

like image 562
John Weisz Avatar asked Apr 13 '16 16:04

John Weisz


People also ask

What is true about property decorator?

@property decorator is a built-in decorator in Python which is helpful in defining the properties effortlessly without manually calling the inbuilt function property(). Which is used to return the property attributes of a class from the stated getter, setter and deleter as parameters.

Are very similar to property decorators but are used for methods instead?

Method decorators are very similar to property decorators but are used for methods instead. This let's us decorate specific methods within our class with functionality. A good example of this is @HostListener .

What is property decorator in angular?

Property decorators are used to decorate the specific properties within the classes. Take a look at @Input() . Imagine that you have a property within the class that you want to have an input binding.

What is @property in Python?

The @property Decorator In Python, property() is a built-in function that creates and returns a property object. The syntax of this function is: property(fget=None, fset=None, fdel=None, doc=None)


1 Answers

There is a little trick to achieve this:

function ArrayLog<K extends string, C extends { [ A in K ]: Array<any> }>(target: C, key: K) {
    /* ... */
}

Or even better (Just found in https://stackoverflow.com/a/47425850/274473):

function ArrayLog<K extends string, C extends Record<K, Array<any>>>(target: C, key: K) {
    /* ... */
}

Unfortunately this only works for public properties, not for private or protected properties...

like image 176
kayahr Avatar answered Oct 05 '22 03:10

kayahr