What is reflect-metadata in typescript
Asked Answered
S

2

112

what are reflect-metadata and its purpose?

What is syntax and purpose of using reflect-metadata?

Can some one provide the example for better understanding of the same?

How can be the reflect metadata helpful in implementing decorators in typescript.

Seminarian answered 17/7, 2017 at 4:13 Comment(1)
This link might help blog.wolksoftware.com/…Mackinaw
W
96

reflect-metadata Allows you to do runtime reflection on types.

The native (non reflect-metadata) version of type inference is much poorer than reflect-metadata and consists only of typeof and instanceof.

More

This blog post covers its features well : http://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from-novice-to-expert-part-4

Willner answered 17/7, 2017 at 4:27 Comment(3)
@barasat Is it the reflection or just Dictionary with key and value pair with some other params like Serializer and Constructor type?Seminarian
@MantuNigam just a dictionary built from the type definition (instead of runtime value assignments)Willner
Should this be imported everywhere where we are using decorators that use the Reflect API? Or is there a way to make tsc import it only once for the entire project?Glochidiate
C
2

One way of using standard Reflect functionality with decorators:

import { performance } from 'perf_hooks';

// common decorator
export function log() {
    return (_target, propertyKey: string, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value;

        descriptor.value = async function (...args) {
            const start = performance.now();

            const result = await originalMethod.apply(this, args);

            const finish = performance.now();

            const ms = Math.round(finish - start);
            console.log(`[${propertyKey}] ${ms}ms`);

            return result;
        };

        return descriptor;
    };
}

// Decorator to log class method or all class methods with Reflect
export function Log(): MethodDecorator & ClassDecorator {
    return (target: any, key?: string, descriptor?: TypedPropertyDescriptor<any>) => {
        if (descriptor) {
            // method decorator
            return log()(target, key, descriptor);
        }

        const methodNames = Reflect.ownKeys(target.prototype);
        methodNames.forEach((methodName: string) => {
            if (methodName !== 'constructor') {
                const methodDescriptor = Reflect.getOwnPropertyDescriptor(target.prototype, methodName);

                const modifiedMethodDescriptor = log()(target, methodName, methodDescriptor);

                Reflect.defineProperty(target.prototype, methodName, modifiedMethodDescriptor);
            }
        });

        // class decorator
        return target;
    };
}

Example:

@Log() // set logging for all Service class methods
class Service {
  @Log() // set logging only for this method
  handleTasks() {}
}

Reflect Documantation

Combust answered 29/6, 2022 at 9:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.