Search code examples
javascripttypescriptamazon-web-servicesaws-lambdaaws-api-gateway

How to extend user defined interface with an already defined interface in typescript?


I have a typescript lambda function which accepts the parameter details.

In my current code I already have a defined interface APIGatewayProxyEventQueryStringParameters. Since this details (query string) have some keys which I want to type define but I also want to use APIGatewayProxyEventQueryStringParameters how should I do that.

Please note: I want to type safe the query string parameters which are coming as request parameters, for those values I am trying to define a type.

I tried something like this

interface detailsProps extends APIGatewayProxyEventQueryStringParameters {
  approve: string,
  name: string
  token: string
}


async function trial(
  actionDetails: actionDetailsProps
) {
...

But when I try to call this function it says Argument of type 'APIGatewayProxyEventQueryStringParameters' is not assignable to parameter of type 'detailsProps'.

export async function main(
  event: APIGatewayProxyEventV2
): Promise<APIGatewayProxyResultV2> {
  try {
    const abc =
      event.queryStringParameters!.xxxxx;

    await trial(event.queryStringParameters!); //error
    return {
      statusCode: 301,
      headers: {
        Location: xxxxx!,
      },
    };
  } catch (error) {
    return {
      body: JSON.stringify({
        message: "oh no",
      }),
      statusCode: 502,
    };
  }
}

Solution

  • You've told Typescript that the trial function's parameter must be a type with approve, name, and token keys. But a APIGatewayProxyEventQueryStringParameters type, which is the type of event.queryStringParameters is not defined as definitely having these three keys. Might have them. Might not.

    There are several ways to satisfy the compiler. Hare are two options.

    Solution 1: Define a new type to narrow the event type. Explicitly tell Typescript to expect the 3 custom key-value pairs in the parameters:

    interface MyProxyEvent extends APIGatewayProxyEventV2 {
        queryStringParameters: detailsProps // note: the convention is to capitalize type definitions!
    }
    
    export async function main(
      event: MyProxyEvent
    

    Solution 2: Check for the existence of the 3 keys. Typescript applys control flow analysis and will take the hint.

    const params = event.queryStringParameters
    
    if (!params?.approve || !params?.name || !params?.token)
        throw new error("Missing a required query parameter!")
    

    Note that nothing you do here will prevent the Lambda being called without the correct query string parameters. Typescript has your back at compile time, but not at run time.