Open ByteSturm opened 2 years ago
https://automapperts.netlify.app/docs/mapping-configuration/type-converters it is intended. You can check this doc page out for more info
Oh ok, thank you for pointing that out. I missed the following line
Instead of throwing an error, AutoMapper will map as-is to respect the dynamic nature of JavaScript. To control the conversions for these types when the properties are matching, we need to supply Type Converters to a specific Mapping
Maybe we can change this in a feature request? At least I would love to have a (global) configuration option which would make Automapper throw an error if the primitive types don't match. As Typescript provides type safety we are loosing it here. This could avoid some runtime errors if you forget to add the TypeConverters. I can understand why to treat the values as-is but I think it could also be an useful feature, introducing this optional type safety.
@ByteSturm we can discuss about it for sure. One main reason I didn't throw an error when first introducing Type Converter was I considered it a big breaking change to start throwing error now.
As for a feature request, I think a better solution would be to incorporate something like zod
to do TRUE schema check against a model's metadata. However, I'm not sure whether I want to include zod
as a dep to @automapper/core
. Maybe a secondary entry point like @automapper/core/validation
would be better. Thoughts?
Right I see, that's a good reason, I fully understand that. Also thanks for changing the labels and title :)
I had a brief look at the zod
project. It looks like a good fit for this use case. Also do I agree on the point of trying not to include it as a dependency in the core project as the behavior in general should be optional. So yes, adding something like @automapper/core/validation
sounds like a good approach to me.
Regarding on how to configure the type checks, so if an error should be thrown or values should be used as-is, I think it should be possible to have different levels as with other mapping configurations. It should be something we can configure per mapping, on profile level and I would prefer to also set it globally when we create the mapper (like the strategy configuration).
I think with this approach you won't have breaking changes, no dependencies in @automapper/core
and it could be flexibly configured on multiple levels.
@ByteSturm Yeah, I'm thinking about something like this
// before
import { createMap, createMapper, addProfile } from '@automapper/core';
// after
// these versions have zod integrated
import { createMap, createMapper, addProfile } from '@automapper/core/validation';
Mapper
level with createMapper
; by using this createMapper
, we can also validate the Source
instead of just the Destination
. Like when you run: this.mapper.map(sourceObject, Source, Destination)
and sourceObject
does not conform to Source
then we can throw validation errorMapping
level with createMap
Profile
level with addProfile
They basically do some forms of 2 things:
destination
object on afterMap
(external) or postMap
(internal) so Zod throws an error.We also need to think about how to suppress the logs/errors on different environment (like in dev mode maybe suppress it but in prod mode, it needs to throw error)
I mostly agree, just some remarks/thoughts I have here:
afterMap
method would make more sense. Then it also catches errors made by the developer when implementing some additional logic for the mapping. But I can also see that some people might have a different opinion on that.@ByteSturm
Slightly off-topic, maybe we can even use Zod to build out the Classes/Interfaces so maybe a separate package like @automapper/zod
π to use in tandem with @automapper/classes
/@automapper/pojos
.
// before with AutoMap
class Foo {
@AutoMap()
foo!: string;
}
// before with PojosMetadataMap.create
interface Foo {
foo: string;
}
PojosMetdataMap.create<Foo>('Foo', {
foo: String
});
// after with zod
const Foo = z.object({
foo: z.string();
}); // explicitly using "z" here but @automapper/zod might expose some abstractions over zod to do extra things
// we have the schema, we can either do
// PojosMetadataMap.create('Foo', Foo);
// or think of a more fluid API for pojos
EDIT: maybe something like this
Ok got your points, fine for me.
Regarding the @automapper/zod
package, so you would use the zod models/schemas internally instead of the Automapper metadata?
Also I doubt that you can omit the original class definition. One might use things like class-validator
on it. If you "force" the developer to use these createModel()
methods to get validation, the developer has to do double the effort and keep both in sync.
Let's say from a users perspective it would be easier to use, if you can infer the zod model / schema from the existing class definition. As far as I understand the code and metadata, you already know which properties have which type.
using zod would make class-validator obsolete imo but I agree there should be something to add addtional decorators if I go with automapper/zod.
I think it can have a positive impact. Zod is pretty powerful and popular in the typescript ecosystem
Is there an existing issue for this?
Describe the issue
Hello everyone,
while introducing Automapper into my project I noticed that the mapping between primitive data types is not type safe. I don't know if this behavior is intended or a bug but I assume it's the second one.
Models/DTOs/VMs
No response
Mapping configuration
No response
Steps to reproduce
Result:
Expected behavior
At least I would expect Automapper to throw an error similar to the one in the case that no mapping between two types exists.
Screenshots
No response
Minimum reproduction code
No response
Package
Other package and its version
No response
AutoMapper version
8.5.0
Additional context
typescript v4.7 Node v16