Deploy Netlify Functions with TypeScript
Atila Fassina

Atila Fassina @atila

About: making code simpler. DX + Serverless

Location:
Berlin
Joined:
Jan 31, 2017

Deploy Netlify Functions with TypeScript

Publish Date: Aug 10 '20
33 9

Netlify has recently reached 1 MILLION DEVELOPERS. That’s a lot of happy consumers. To celebrate that, here‘s a step-by-step guide to deploy your very own Netlify Function with TypeScript.

📹 If you prefer, you can have this post as a screencast video.

Please don’t forget to 👍 and 🔔 on your way out if it helped you. It would help me a ton!!! 💕

Also, check the whole source code on github/monster-as-a-service

Configuring netlify.toml

Our first needed step is to configure our Netlify deploy. If you prefer, you can set this up on the dashboard as well, but I find the configuring file more straightforward. To each their own, though.

[build]
  command = "yarn build"
  functions = "lambda"

# this is actually a Rewrite
# totally optional, but makes up for
# a much better UX
[[redirects]]
  from = "/"
  to = "/.netlify/functions/index"
  status = 200
Enter fullscreen mode Exit fullscreen mode

Teaching TypeScript to Babel

Now we need to setup our .babelrc so Babel can use the TypeScript compiler (tsc)

{
  "presets": [
    "@babel/preset-typescript",
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": true
        }
      }
    ]
  ]
}
Enter fullscreen mode Exit fullscreen mode

Create your script tasks

Almost done, run over to your package.json and add the two tasks you’re going to need:

"build": "netlify-lambda build src",
"ts-check": "tsc --noEmit --lib ES2015 ./src/*.ts"
Enter fullscreen mode Exit fullscreen mode

The only mandatory one is build, but I imagine you will want to be able to check all your types at some point. For any production level TypeScript code I’d consider a good practice to check your types on CI pipeline, at the very least.

🚨 That's because Babel will not check your types, simply run the compiler.

Bare bones function with TypeScript

The only thing you need to have a working Netlify Function is to export a handler method from your .js or .ts file. Netlify Functions run AWS-Lambdas under the hood. So, to have your handler typed, you can simply add types/aws-lambda and you’re good to go.

Here’s a useful example:

import { APIGatewayEvent, Context } from 'aws-lambda'

export async function handler (
  event: APIGatewayEvent,
  context: Context
) {

  const { msg } = event.queryStringParameters

  return {
    statusCode: 200,
     headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ msg })
  }
}
Enter fullscreen mode Exit fullscreen mode

In that case, if you hit https://your-lambda.netlify.app?msg=BlackLivesMatter if will return the following json:

{ 
  "msg": "BlackLivesMatter"
}
Enter fullscreen mode Exit fullscreen mode

I recommend you to install netlify-dev globally so you can simulate production environment in your machine. If you have the package, you can run netlify dev and it will boot up a server for you and expose your lambda on https://localhost:8888 by default.

If linked to your Netlify Account, the CLI will also allow you to deploy your project without pushing it to anywhere.

Deploy

Netlify offers you a few ways of deploying your code. The most common is by setting Continuous Deployment by integrating it with your Github, Gitlab, or Bitbucket account.

Another way to do it though, is using Netlify-Dev CLI and hitting netlify deploy.

💌

In case you have found this post useful, please consider sharing it with your network, that would help me a lot to continue sharing posts like this and others. 😁

Comments 9 total

  • Alexandru-Dan Pop
    Alexandru-Dan PopAug 10, 2020

    Nice tutorial!

    • Atila Fassina
      Atila FassinaAug 10, 2020

      Thanks a lot, Alexandru!

      I'm glad it was useful! 💪

  • Gregori Piñeres
    Gregori PiñeresAug 11, 2020

    Great article, thanks 🤟

    • Atila Fassina
      Atila FassinaAug 11, 2020

      Thanks a lot, Gregori!

      I'm very glad you liked it! 😁

  • Arkadiy Kukarkin
    Arkadiy KukarkinSep 24, 2020

    the sample snippet doesn't build for me:

    error TS2339: Property 'msg' does not exist on type '{ [name: string]: string; } | null'.
    
    8   const { msg } = event.queryStringParameters
    
    Enter fullscreen mode Exit fullscreen mode
    • Arkadiy Kukarkin
      Arkadiy KukarkinSep 24, 2020

      fixed it as follows:

      interface EchoQueryParams {
        msg?: String
      }
      ...
      const { msg } = event.queryStringParameters as EchoQueryParams
      

      (note, this won't actually enforce runtime type checks, but it will make it compile)

    • Atila Fassina
      Atila FassinaSep 25, 2020

      Interesting... it works well for me, code runs as expected and ts-checks return no warnings or errors

      ❯ tsc --version
      Version 4.0.3
      
      ❯ yarn ts-check
      yarn run v1.22.5
      $ tsc --noEmit --lib ES2015 ./src/*.ts
      ✨  Done in 0.77s.
      

      Plus { msg } definitely exists in type [name: string] : string 😜

      • Arkadiy Kukarkin
        Arkadiy KukarkinSep 26, 2020

        ok, I see the issue, the tsconfig I was inheriting from (node12) sets strict: true, which does not pass in this case

        specifically, it seems that this fails because strict implies strictNullChecks, and given that this type is nullable it won't pass (if I cast it as { [name: string] : string } it's ok)

  • Carl Vuorinen
    Carl VuorinenOct 23, 2020

    Thanks, nice tutorial. That .babelrc with targets node:true made it work (the example given in netlify-lambda README did not work for me without adding that).

    Also, the redirect trick was nice, haven't used Netlify redirects before. But I changed it a little bit since I have a project with multiple functions:

    [[redirects]]
      from = "/*"
      to = "/.netlify/functions/:splat"
      status = 200
    
    Enter fullscreen mode Exit fullscreen mode
Add comment