Closed hikinine closed 6 months ago
hey @hikinine,
Thank you so much for opening this issue! Your suggestion for improving the toObject method is greatly appreciated. Indeed, enhancing it in this way has been on radar, especially considering its limited typing capabilities up to the first level and its compatibility only with TypeScript versions prior to 5.1.
It's worth noting that the current implementation of toObject may not fully meet your expectations due to its limitations. Specifically, it only provides typing up to the first level, and it's compatible only with TypeScript versions prior to 5.1.
Moreover, implementing this enhancement might require adjustments to the automapper functionality. Currently, automapper shortens objects that have only one attribute, which could affect the expected behavior of the method.
For instance, given the following example:
type Props = { value: string };
class Name extends ValueObject<Props> {
public static init(name: string): Name {
return new Name({ value: name });
}
}
const name = Name.init("Jane");
console.log(name.toObject());
// Output: "Jane"
The output will only be the value, as automapper optimizes the object size by shortening the path.
Entityt Example:
type Props = { name: Name, age: Age };
class User extends Entity<Props> {
public static init(name: Name, age: Age): User {
return new User({ name, age });
}
}
const user = User.init(name, age);
const model = user.toObject();
// Output: { "name": "Jane", "age": 21 }
As pointed out, the output is
{ "name": "Jane", "age": 21 }
instead of { "name": { "value": "Jane" }, "age": { "value": 21 } }
Ensuring that the toObject method returns read-only objects would be a significant enhancement, preventing unintended modifications to the state.
By returning read-only objects, we can provide an additional layer of protection against accidental data manipulation, while still allowing access to the object's properties for inspection purposes.
For example, consider the following scenario:
const company = Company.toObject();
company.users.push(user); // This should ideally result in a compilation error due to read-only nature
With read-only objects, attempts to modify the object's properties directly would be flagged at compile time, promoting safer coding practices and reducing the risk of runtime errors.
Hi @4lessandrodev
As pointed out, the output is { "name": "Jane", "age": 21 } instead of { "name": { "value": "Jane" }, "age": { "value": 21 } }
Thats the goal, only the primitive object. I've tried on my own and looks like autoMapper returns exactly the same result as Serializer types.
Another important point Ensuring that the toObject method returns read-only objects would be a significant enhancement, preventing unintended modifications to the state.
Bem pensado, looks like autoMapper already creates a safe copy object, not referenced to the own aggregate props. But yes, should be nice turn everything on the Serializer result as readonly just for not miss understading.
Something that is bothering me is the need to create a "getRawProps" method. The serializer does not necessarily need an implementation of the Props return. Just props inference at the typescript level. But I couldn't think of anything better than the method (which could be an antipattern since the intention is to protect properties and allow access only with the domain layer intelligence)
Anyway, let me know what you think.
Should I open this pull request?
@hikinine Absolutely, Feel free to go ahead and open it. We can then work on utilizing the existing toObject method to ensure that all type and value inference tests for the following scenarios pass:
Additionally, let's make sure to include an example of read-only implementation as follows:
public toObject(): Readonly<Props> {
return Object.freeze({ ... });
}
Let's collaborate on this to ensure comprehensive testing and adherence to the desired functionality. Looking forward to working on this together!
Saudações,
Entity.toObject method may not have much usability for production environments, but during development it is interesting to be able to check a serialized form of the Aggregate/Entity.
Proposal
Dynamically type the toObject function for the exact return of the autoMapper (primitive of all aggregates recursively).
Requirements
Include an method (or property) on base class (GettersAndSetters), OR, include a new method in each class. this method should return Props type
something like
The reason for this is that you cannot infer a type that is protected/private (maybe I'm wrong).
Once we have the Entity Props available
USAGE