node.js - AWS Lambda med TypeScript får Kan inte läsa egenskap av undefined inne i asynkron handler


Typskript-nybörjare här. Jag arbetar på en AWS Lambda-funktion genom att använda Typskript med klasser. Jag exporterar en async-hanterare i slutet. När jag anropar min funktion från AWS SAM CLI får jag ett fel av;

{"errorType":"TypeError","errorMessage":"Kan inte läsa egenskapen 'test' av undefined","stack":["TypeError: Kan inte läsa egenskapen 'test' av undefined"," vid Runtime.handler (/var/task/src/lambda/create-cost-lambda.js:12:56)"," vid Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"]}

skapa-kostnad-lambda.ts

class CreateCostLambda {
    private readonly foobarRepository: FoobarRepository;

    constructor() {
        this.foobarRepository = new FoobarRepository();
    }

    async handler(event: APIGatewayProxyEventV2) : Promise<APIGatewayProxyResultV2> {
        const result = await this.foobarRepository.test();
        console.log(result);

        return {
            body: JSON.stringify(result),
            statusCode: 200,
        };
    }
}

export const { handler } = new CreateCostLambda();

Här är en mycket grundläggande klass som representerar ett arkiv.

foobar-förråd.ts

export class FoobarRepository {
    private readonly awesomeValue: string;

    constructor() {
        this.awesomeValue = 'John Doe';
    }

    async test(): Promise<string> {
        return this.awesomeValue;
    }
}

Jag är nästan säker på att det beror på sättet jag exporterar hanteraren och hur aws-sam internt kör hanteraren. Men jag kan ha fel och det kan vara en TypeScript-grej som jag missar. Vänligen låt mig veta om du behöver mer information och stort tack för hjälpen!

Svar #1

Den korta versionen är att om du passerar en funktion från en klass, förlorar den sin referens till this.

Jag skulle lösa detta på följande sätt:

const createCostLambda = new CreateCostLambda();
export const handler = createCostLambda.handler.bind(createCostLambda);

Du kan också fråga dig själv, behöver detta vara en klass? Svaret är: förmodligen inte. Det finns inget att vinna på detta i ditt exempel.

const foobarRepository = new FoobarRepository();
export async function handler(event: APIGatewayProxyEventV2) : Promise<APIGatewayProxyResultV2> {
   const result = await foobarRepository.test();
   console.log(result);

   return {
     body: JSON.stringify(result),
     statusCode: 200,
   };
}

Färre rader, inget onödigt tillstånd. Javascript är inte Java=)