I'm trying to handle Dynamo DB stream events in a Lamdba function written in TypeScript. My code is something like this:
import { DynamoDBStreamEvent } from 'aws-lambda'
import { unmarshall } from '@aws-sdk/util-dynamodb'
const handler = async (event: DynamoDBStreamEvent): Promise<void> => {
for (const record of event.Records) {
if (record.dynamodb?.NewImage) {
const newImage = unmarshall(record.dynamodb.NewImage)
// not relevant from this point on...
}
}
}
The problem is, I get a type mismatch on the line, where unmarshall is called:
Argument of type '{ [key: string]: AttributeValue; }' is not assignable to parameter of type 'Record<string, AttributeValue>'.
'string' index signatures are incompatible.
Type 'AWSLambda.AttributeValue' is not assignable to type 'import("/path/to/project/node_modules/@aws-sdk/client-dynamodb/dist-types/models/models_0").AttributeValue'.
Property '$unknown' is missing in type 'AttributeValue' but required in type '$UnknownMember'.ts(2345)
models_0.d.ts(5057, 9): '$unknown' is declared here.
(property) StreamRecord.NewImage?: {
[key: string]: AttributeValue;
}
That is, the NewImage
in the DynamoDBStreamEvent
is declared in package @types/aws-lambda
and uses an AttributeValue
type defined there, while the unmarshall
expects the data using type AttributeValue
defined in package @aws-sdk/client-dynamodb
, and those types are not compatible.
In practice, both of these different AttributeValue
types define the Dynamo DB JSON format, but they are incompatible according to TypeScript typing.
I can workaround this by changing the unmarshall call to:
const newImage = unmarshall(record.dynamodb?.NewImage as any)
and it works - it unmarshalls the DynamoDB JSON format to my native JSON format correctly - but that defeats the purpose of typing. Is there any more correct way of handling this situation, or is this a bug?