Skip to content

Instantly share code, notes, and snippets.

@Sleavely
Last active December 3, 2021 09:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sleavely/3c43829e5ff8096aa073716ea947c090 to your computer and use it in GitHub Desktop.
Save Sleavely/3c43829e5ff8096aa073716ea947c090 to your computer and use it in GitHub Desktop.
Solving the AWS Lambda payload-might-be-undefined problem in Typescript with interface overloads

I ran in to some trouble when I wanted to use more explicit types than the APIGatewayProxyEventQueryStringParameters or APIGatewayProxyEventPathParameters ones tied to the base event, so I figured I'd give it a shot and jot it down for my own future reference.

Please leave a comment if you've got a cleaner idea 💌

export const getEvent = (): AWSLambda.APIGatewayProxyEvent => {
return req.event
}
interface QueryStringParams {
(): AWSLambda.APIGatewayProxyEventQueryStringParameters
<Type>(): Type // An overload that we can use to explicitly type the returned value
}
export const getQueryStringParams: QueryStringParams = () => {
return getEvent().queryStringParameters ?? {}
}
import { getQueryStringParams } from './my-lambda-utility-library.ts'
// This allows us to do things like:
interface DatabaseListQuery {
user: string
potato: string
}
// Because we define which type we expect in the result,
// we wont get the error "query.user is not part of APIGatewayProxyEventQueryStringParameters"
const query = getQueryStringParams<DatabaseListQuery>()
console.log(query.user.toUpperCase())
// If we dont, we get the default errorneous behavior:
const brokenQuery = getQueryStringParams()
console.log(brokenQuery.user.toUpperCase()) // <- Object is possibly 'undefined'.ts(2532)
import { setEvent, getQueryStringParams } from './my-lambda-utility-library.ts'
// More realistically it might look like this
interface DatabaseListQuery {
user: string
potato: string
}
const getDataFromDatabase = (userid: string): string => 'Hey world'
export const myAwesomeHandler = (event: AWSLambda.APIGatewayProxyEvent, context: AWSLambda.Context): AWSLambda.APIGatewayProxyResult => {
setEvent(event, context)
const query = getQueryStringParams<DatabaseListQuery>()
// This would normally fail with APIGatewayProxyEventQueryStringParameters because string is required, undefined not allowed
const data = getDataFromDatabase(query.user)
return { statusCode: 200, body: JSON.stringify(data) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment