# Mapping Concept

As long as there are no decorators the mapper decides by the value type, to which DynamoDB attribute type it will map.

{% hint style="info" %}
We map all properties (`Object.getOwnPropertyNames(objectToMap)`) by default. Use the [@Transient](https://shiftcode.gitbook.io/dynamo-easy/~/edit/drafts/-LYRfBDOu4fbNeiERleF/api/model/decorators#transient) decorator to prevent a property from being mapped.
{% endhint %}

## Empty Values

`(null & undefined)` are treated as empty values and are not mapped to an attribute value.

{% code title="JS value" %}

```javascript
{
    "name": null,
    "age": 23,
    "nationality": undefined
}
```

{% endcode %}

{% code title="DynamoDB value" %}

```javascript
{
    "age": {N: "23"} 
}
```

{% endcode %}

## Without Decorator

| JS Type                                                     | Mapped DynamoDB type                                               |                                                                                    |
| ----------------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| boolean                                                     | \[BOOL]                                                            |                                                                                    |
| string                                                      | \[S]tring                                                          |                                                                                    |
| number                                                      | \[N]umber                                                          |                                                                                    |
| Array                                                       | \[L]ist                                                            |                                                                                    |
| <p>Set\<number></p><p>Set\<string></p><p>Set\<Binary\*></p> | <p>\[N]umber\[S]et</p><p>\[S]tring\[S]et</p><p>\[B]inary\[S]et</p> | <p>Mixed item types are</p><p>only supported with </p><p>decorator (see below)</p> |
| Object                                                      | \[M]ap                                                             |                                                                                    |

> \*Binary is not yet supported

{% hint style="danger" %}
Avoid using Set for types other than string|number|Binary **without decorator**. In this case make sure to add the`@CollectionProperty({opt})`

`Set<CustomType>` would be mapped implicitly to \[L]ist of \[M]aps. But when parsing the Attribute from DynamoDB, there's no information about the Set and will therefore be parsed to an array. To fix this, use the @CollectionProperty() decorator.
{% endhint %}

## With Decorator

| JS Type + CollectionProperty decorator                                                                     | DynamoDB Type      |                                                                                 |                                    |
| ---------------------------------------------------------------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------- | ---------------------------------- |
| <p><code>@CollectionProperty()</code></p><p><code>Set\<string                                              | number></code></p> | \[L]ist                                                                         | only list supports different types |
|                                                                                                            |                    |                                                                                 |                                    |
| <p><code>@CollectionProperty({ sorted: true })</code></p><p><code>Set\<string></code></p>                  | \[L]ist            | only list preserves the order                                                   |                                    |
| <p><code>@CollectionProperty({ sorted: true })</code></p><p><code>Set\<number></code></p>                  | \[L]ist            | only list preserves the order                                                   |                                    |
|                                                                                                            |                    |                                                                                 |                                    |
| <p><code>@CollectionProperty({ itemType: CustomType\* })</code></p><p><code>Set\<CustomType></code></p>    | \[L]ist            | only makes sense when CustomType is @Model decorated - will be used for mapping |                                    |
| <p><code>@CollectionProperty({ itemType: CustomType\* })</code></p><p><code>Array\<CustomType></code></p>  | \[L]ist            | only makes sense when CustomType is @Model decorated - will be used for mapping |                                    |
|                                                                                                            |                    |                                                                                 |                                    |
| <p><code>@CollectionProperty({itemMapper:CustomTypeMapper})</code></p><p><code>Set\<CustomType></code></p> | \[(N\|S\|B)S]et    | itemMapper must return N\|S\|B - Attribute                                      |                                    |

> \*If CustomType is string|number|Binary, it will be mapped to the respective \[S]et

{% hint style="info" %}
Generic information is never available due to some serialization limitations of the typescript compiler. Therefore you can provide the itemType to the @CollectionProperty decorator.
{% endhint %}
