I am getting an error while trying to access an object that I know exists.
When trying to access the iam
property of the event.authorizer object returned from AWS Cognito, an error displays in both VS Code and the terminal once I run it.
src/private.ts:9:33 - error TS2339: Property 'iam' does not exist on type '{ jwt: { claims: { [name: string]: string | number | boolean | string[]; }; scopes: string[]; }; }'.ts(2339)
This error is especially puzzling, because when I print the "event" object, it shows evidence that it exists.
Output of event.requestContext
:
{"statusCode":200,"headers":{"Content-type":"text/json"},"body":"{\"event\":{\"accountId\":\"365416766059\",\"apiId\":\"8ihwuguj40\",\"authorizer\":{\"iam\":{\"accessKey\":\"ASIAVKFE... 1068 more characters"}
This shows that there is an object iam
that is the value of the authorizer
attribute. This is proof that it exists. So why does VS Code have an issue with it?
I ran the code using npx sst start
which runs the code with no issues, and returns the expected event
object with authorizer
and awt
nested objects.
Full code for lambda function is below.
import { APIGatewayProxyHandlerV2 } from "aws-lambda"
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
const rand = Math.floor(Math.random() * 10)
const authoriser = event.requestContext.authorizer
const accountId = authoriser?.iam.accountId ?? "" // Problem starts with reference to "iam" here.
return {
statusCode: 200,
headers: {"Content-type": "text/json"},
body: JSON.stringify({ message: `Private random number: ${rand}`, accountId: accountId}),
}
}
I have tried:
- Making
iam
an optional by appending a question mark. - Using a try-catch block around the statement.
CodePudding user response:
event
is mis-typed.
By typing your function as APIGatewayProxyHandlerV2
, you have told typescript that event
is of type APIGatewayProxyEventV2
(typedef here). The actual event
from Lambda you are getting is not that type, as evident from the log output.
// what typescript thinks your event is:
export interface APIGatewayProxyEventV2 {
version: string;
routeKey: string;
rawPath: string;
rawQueryString: string;
cookies?: string[] | undefined;
headers: APIGatewayProxyEventHeaders;
queryStringParameters?: APIGatewayProxyEventQueryStringParameters | undefined;
requestContext: {
accountId: string;
apiId: string;
authorizer?: {
jwt: {
claims: { [name: string]: string | number | boolean | string[] };
scopes: string[];
};
} | undefined;
domainName: string;
domainPrefix: string;
...etc
So you need to fix the event
type. What are your options?
- Search for a pre-defined type that matches the lambda event
- Be lazy and self-hating:
event: any
- Define a minimum type that satisfies the contract:
event: MyLambdaEvent
// custom event type
// match the required parts of the event object lambda is actually giving you
interface MyLambdaEvent {
authorizer: {
iam: {
accountId: string
}
}
}