Property decorator only for a specific property ty

2020-07-14 05:39发布

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?

2条回答
地球回转人心会变
2楼-- · 2020-07-14 06:02

The error you are getting is due to the return expression missing.

Try something along the lines:

export function Decorator(fn:any) {
  return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<Array>) => {
    if (Reflect.getMetadata("design:type", target, propertyKey) !== Array) {
        throw new TypeError();
    } 
    return descriptor;
  };
}
查看更多
老娘就宠你
3楼-- · 2020-07-14 06:24

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...

查看更多
登录 后发表回答