Reflect Metadata Types in TypeScript
This challenge focuses on implementing a simplified version of TypeScript's reflect-metadata functionality. Reflect metadata allows you to attach arbitrary data to classes, methods, properties, and parameters, enabling powerful features like dependency injection, serialization, and validation. Your task is to create a system that allows you to define, retrieve, and update metadata associated with these TypeScript constructs.
Problem Description
You need to implement a basic reflect metadata system in TypeScript. This system should allow you to:
- Define Metadata: Attach metadata (represented as strings) to classes, methods, properties, and parameters.
- Retrieve Metadata: Retrieve the metadata associated with a given target (class, method, property, or parameter).
- Update Metadata: Modify existing metadata or add new metadata to a target.
The system should support metadata keys and values, allowing you to organize and identify different types of metadata. The metadata should be stored in a simple key-value format. You are not required to implement complex features like inheritance of metadata or automatic metadata discovery. Focus on the core functionality of defining, retrieving, and updating metadata.
Key Requirements:
- Create a
Metadataclass to manage metadata storage. - Implement functions
defineMetadata,getMetadata, andupdateMetadata. - These functions should accept a target (e.g., a class constructor, a function, a string representing a property name), a metadata key (string), and a metadata value (string).
- The
defineMetadatafunction should associate the value with the key for the given target. - The
getMetadatafunction should retrieve the value associated with the key for the given target. If no metadata exists for the key, it should returnundefined. - The
updateMetadatafunction should update the value associated with the key for the given target. If the key doesn't exist, it should create it.
Expected Behavior:
- Metadata should be stored and retrieved correctly for different target types.
- The system should handle cases where metadata does not exist for a given key.
- The
updateMetadatafunction should correctly update existing metadata and create new metadata as needed.
Edge Cases to Consider:
- What happens if the target is
nullorundefined? (ReturnundefinedforgetMetadataand throw an error fordefineMetadataandupdateMetadata). - What happens if the key is
nullorundefined? (Throw an error for all functions). - What happens if the value is
nullorundefined? (Allow it, it's a valid metadata value).
Examples
Example 1:
Input:
class MyClass {}
const metadataKey = 'description';
const metadataValue = 'This is a test class';
defineMetadata(MyClass, metadataKey, metadataValue);
Output:
'This is a test class'
Explanation:
We define metadata with the key 'description' and value 'This is a test class' on the MyClass class. getMetadata(MyClass, metadataKey) retrieves the value.
Example 2:
Input:
class MyClass {}
const metadataKey = 'description';
defineMetadata(MyClass, metadataKey, 'Initial Description');
updateMetadata(MyClass, metadataKey, 'Updated Description');
Output:
'Updated Description'
Explanation:
First, we define metadata. Then, we update it. getMetadata(MyClass, metadataKey) retrieves the updated value.
Example 3:
Input:
class MyClass {}
const metadataKey = 'nonExistentKey';
Output:
undefined
Explanation:
We attempt to retrieve metadata for a key that doesn't exist. The function should return undefined.
Constraints
- All metadata keys and values must be strings.
- The target can be a class constructor function, a function, or a string representing a property name.
- The system should be reasonably efficient for small numbers of metadata entries (performance is not a primary concern for this challenge).
- Error handling should be implemented for invalid inputs (null/undefined keys/targets).
Notes
- Consider using a simple JavaScript object to store the metadata.
- Think about how to handle different target types (classes, methods, properties).
- This is a simplified implementation; a real-world reflect-metadata system would be more complex.
- Focus on clarity and correctness over advanced optimization techniques. The goal is to demonstrate understanding of the core concepts.