Search code examples
typescriptamazon-dynamodb

How can I map a DynamoDB AttributeMap type to an interface?


Say I have a typescript interface:

interface IPerson {
    id: string,
    name: string
}

And I run a table scan on a persons table in dynamo, what I want to be able to do is this:

const client = new AWS.DynamoDB.DocumentClient();

client.scan(params, (error, result) => {
    const people: IPerson[] = result.Items as IPerson[];
};

I am getting the error Type 'AttributeMap[]' cannot be converted to type 'IPerson[]'

Obviously they are different types, however the data structure is exactly the same. My question is how can I essentially cast the dynamo AttributeMap to my IPerson interface?


Solution

  • The right way to do this is by using the AWS DynamoDB SDK unmarshall method.


    JavaScript AWS SDK V3 (post December 2020)

    Use the unmarshall method from the @aws-sdk/util-dynamodb package.

    Docs Example.

    const { unmarshall } = require("@aws-sdk/util-dynamodb");
    
    unmarshall(res.Item) as Type;
    

    Side note: the AWS DynamoDB JavaScript SDK provides a DynamoDBDocumentClient which removes this whole problem and uses normal key value objects instead.


    The previous version of the JavaScript AWS SDK (pre December 2020)

    Use the AWS.DynamoDB.Converter:

    // Cast the result items to a type.
    const people: IPerson[] = result.Items?.map((item) => Converter.unmarshall(item) as IPerson);
    

    Doc for unmarshall():

    unmarshall(data, options) ⇒ map

    Convert a DynamoDB record into a JavaScript object.

    Side note: the AWS DynamoDB JavaScript SDK provides a DynamoDBDocumentClient which removes this whole problem and uses normal key value objects instead.