如何在TypeScript中定义DynamoDB Query查询结果的类型结构?
Great question—this is a common pain point when working with DynamoDB's DocumentClient in TypeScript, since the default return type is too generic to recognize your specific table fields. Here's how to fix it cleanly:
1. Define Your Data Model Interface
First, create a TypeScript interface that matches the exact shape of items in your UnsubscriptionTokens table. Include every field you expect to retrieve, including the id field you need:
interface UnsubscriptionTokenItem { id: string; unsubscriptionToken: string; // Add any other fields present in your table here (e.g., createdAt, userId) }
2. Use the DocumentClient's Generic query Method
The DynamoDB DocumentClient's query method supports a generic parameter that lets you specify the type of items returned in the result. This tells TypeScript exactly what shape to expect for each entry in result.Items:
const request: DynamoDB.DocumentClient.QueryInput = { TableName: UnsubscriptionTokensRepository.TABLE_NAME, IndexName: 'TokenIndex', KeyConditionExpression: 'unsubscriptionToken = :unsubscriptionToken', ExpressionAttributeValues: { ':unsubscriptionToken': token } }; // Pass your custom interface as the generic argument to `query` const result = await this._documentClient.query<UnsubscriptionTokenItem>(request).promise(); // Critical: Handle empty results to avoid runtime errors if (!result.Items || result.Items.length === 0) { throw new Error(`No unsubscription token found for value: ${token}`); } // Now TypeScript recognizes the `id` field without type errors return result.Items[0].id;
Bonus: Reduce Repetition with a Wrapper Method (Optional)
If you query this table frequently, wrap the DocumentClient's query logic in a repository function that enforces your type automatically:
async function getUnsubscriptionToken(token: string): Promise<UnsubscriptionTokenItem | undefined> { const request: DynamoDB.DocumentClient.QueryInput = { TableName: UnsubscriptionTokensRepository.TABLE_NAME, IndexName: 'TokenIndex', KeyConditionExpression: 'unsubscriptionToken = :unsubscriptionToken', ExpressionAttributeValues: { ':unsubscriptionToken': token } }; const result = await this._documentClient.query<UnsubscriptionTokenItem>(request).promise(); return result.Items?.[0]; }
This way, you won't have to specify the generic parameter every time you run a query against this table.
内容的提问来源于stack exchange,提问作者Raheel

