> For the complete documentation index, see [llms.txt](https://aerocode.gitbook.io/tynamo/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://aerocode.gitbook.io/tynamo/expression/differences-from-dynamo.md).

# Differences from Dynamo

### Differences from Dynamo

Tynamo does not have to list every argument name used in an expression. This is because properties in Value Item (beginning with `:`) or entity properties (beginning with `#` ) are automatically written down. Consider the following expression.

```typescript
{
    conditionalExpressions : "attribute_not_exists(#id) and :a < :b"
}
```

The above expression requires one entity property and two value property. Thus, Tynamo infers the following objects:

```typescript
{
    ExpressionAttributeNames : {
        "#id" : "id"
    },
    ExpressionAttributeValues : {
        ":a" : { N|S|B : "?"},
        ":b" : { N|S|B : "?"}
    }
}
```

However, `ExpressionAttributeValues` ​​is an argument of `AttributeMap` type, which violates Tynamo  design principles. As an alternative, use the following value class:

```typescript
@DynamoEntity()
class MyExpressionValue {
    @DynamoProperty({ keyType: KeyType.hash })
    a!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    b!: number;
    
    constructor(a:number, b:number){
        this.a = a;
        this.b = b;
    }
}
```

{% hint style="info" %}
Currently, one `HASH` must be required in the ValueEntityClass also.
{% endhint %}

Attempting to use an argument that is not in the `EntityClass` or `ValueEntityClass` occurs error.

### Custom EntityPropertyName

It is also possible to set an alias for the EntityProperty. If you want to use the name `#identifier` instead of `id`, you can pass it explicitly in `ExpressionAttrubuteNames`.

```typescript
{
    conditionalExpressions : "attribute_not_exists(#identifier)",
    ExpressionAttributeNames : {
        "#identifier" : "id"
    }
}
```

Inferences made by Tynamo may conflict with what you explicitly conveyed. In this case, use the one passed explicitly.

```typescript
{
    conditionalExpressions : "attribute_not_exists(#name)",
    ExpressionAttributeNames : {
        "#name" : "id"
    }
}
```

Although a  `name` exists in the entity, it is used as aslias of `id`.

### Skip unnecessary elements

Dynamo raises an error if there is a declared but unused value name. Tynamo finds these elements and helps them to be omitted at the time of the actual call. For example,

```typescript
@DynamoEntity()
class ValueItem {
    @DynamoProperty({ keyType: KeyType.hash })
    a!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    b!: number;

    constructor(a: number, b: number) {
        this.a = a;
        this.b = b;
    }
}

{
    conditionalExpressions : "attribute_not_exists(#id)",
    ExpressionAttributeNames: {
        "#unused" : "name"
    },
    ExpressionAttributeValues : new ValueItem(0, 0)
}
```

In the expression above, `#unused`, `:a`, and `:b` are declared but not used. Dynamo raises an error if there is such an element, but Tynamo sends only the element that is actually used so no error occurs. It is good for `DynamicExpression`.

### Example

```typescript
@DynamoEntity()
class Cat {
    @DynamoProperty({ keyType: KeyType.hash })
    id!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    name!: string;

    constructor(id: number, name: string) {
        this.id = id;
        this.name = name;
    }
}

@DynamoEntity()
class ValueItem {
    @DynamoProperty({ keyType: KeyType.hash })
    a!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    b!: number;

    constructor(a: number, b: number) {
        this.a = a;
        this.b = b;
    }
}

const tynamo: Tynamo = new Tynamo({
    region: "ap-northeast-2",
    endpoint: "http://localhost:8000"
});

await tynamo.putItem({
    Item: new Cat(666, "garfield"),
    ConditionExpression: "attribute_not_exists(#id) and :a < :b",
    ExpressionAttributeValues : new ValueItem(5, 0)
});
```

The above `putItem`  opreration is always fails because `:a < :b` is false.
