How to use Typescript with AWS Amplify Function

Vincent Delacourt
6 min readMay 6, 2020

Compile your typescript function and lint it before pushing it. Don't push useless library to the cloud and keep your function as small as it should be.

Init your Amplify project

npm init private
amplify init

Then choose as below (or according to your need)

Make VS Code ready for Typescript

If you don’t use VS Code, you can skip this.

Add Settings and Extensions for VS Code

mkdir .vscodecurl -o .vscode/extensions.json https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.vscode_extensions.jsoncurl -o .vscode/settings.json https://gist.githubusercontent.com/vdelacou/eeb8931e510218dac1464d3cd592722c/raw/868452b13dd73bf0f9f7b4c5e76143f02583647c/.vscode_settings.json

Add Prettier and Editorconfig configuration

curl -o .prettierrc https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.prettierrccurl -o .prettierignore https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.prettierignorecurl -o .editorconfig https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.editorconfig

As it’s not the topic here, I let you check the files at their gist adresses.

Create your first function

amplify add function

We create a new function named concatenate as below:

Setup our Typescript Function

First, go the function folder and delete index.js and package.json

cd amplify/backend/function/concatenate/srcrm index.js package.json

Create a ts folder, where we will put our typescript code

cd ..
mkdir ts
cd ts

Start our typescript project

npm init privatenpm install aws-lambda aws-sdknpm install --save-dev typescript @types/node @types/aws-lambda eslint@6.8.0 eslint-plugin-flowtype@3 @typescript-eslint/eslint-plugin@2.31.0 eslint-config-airbnb-base@latest eslint eslint-plugin-import @typescript-eslint/parser@2.31.0 eslint-config-airbnb-typescript prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks@2.5.0

aws-lambda library do not need to be in prod dependencies as it will be included automatically in our AWS Lambda when deployed.

Add the tsconfig.json for our function

curl -o tsconfig.json https://gist.githubusercontent.com/vdelacou/eeb8931e510218dac1464d3cd592722c/raw/b689f79c9dea03accb4327b06a16df99448f37f7/tsconfig.json

Then set the configuration for Eslint

curl -o .eslintrc.json https://gist.githubusercontent.com/vdelacou/d6a880059777451a913acd962b8e43a8/raw/.eslintrc.jsoncurl -o .eslintignore https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.eslintignore

Time to code our first function

touch index.ts

A Lambda function takes an event in input and gives a result. The input event can be everything, for example, an S3 event, a Cognito event, a DynamoDB event, or anything you want. Lambda is often associated with Api Gateway Event, so it becomes confusing to use a lambda without calling an API, but a lambda it's just a function.

We will make an easy function. As the default event given by the generated Hello World function is :

{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}

We will just make a function that takes this event and return a string with the key concatenate. Just copy this to your index.ts file

import { Callback, Context, Handler } from 'aws-lambda';interface TriggerEvent {
key1: string;
key2: string;
key3: string;
}
export const handler: Handler<TriggerEvent, string> = (event: TriggerEvent, context: Context, callback: Callback<string>) => {
const concatKey = `${event.key1} ${event.key2} ${event.key3}`;
callback(null, concatKey);
};

Try our function locally

In your ts folder add this to your package.json

...
"scripts": {
"tsc": "npm run lint && tsc",
"lint": "eslint . --ext .ts"
}
...

And then launch:

npm run tsc

You can now see in the js folder the compiled fileindex.js

To launch locally

amplify mock function concatenate

Choose the file src/event.json when asked and then you can see the result

Publish your function

At the root folder add this to your package.json

...
"scripts": {
"amplify:concatenate": "cd amplify/backend/function/concatenate/ts && npm install && npm run tsc && cd -"
},
...

Then push it:

amplify push

You can now open the console

amplify console

Find "Functions" and then click on "View on Lambda"

As you can see there is only the index.js and event.json publish to the lambda, so we have kept it simple and very light.

You can now use the content of event.json to test your function "online" by selecting "configure test event" at the top right

Function with dependencies

We will try to make a simple function which uses i18n to return a translation

amplify add function

Choose the function name : translate then do exactly the same as above with the concatenate function

In the folder src do the following:

npm init privatenpm install i18n

Also, change the event.json to

{
"lang": "fr"
}

Create a folder for the locales and create translations files

mkdir locales
cd locales
echo "{ \"title\": \"Translation\" }" > en.json
echo "{ \"title\": \"Traduction\" }" > fr.json

So now compare to the previous function we also have a package.json in the src folder.

Then in the ts folder we also install the i18n library:

npm install i18n
npm install --save-dev @types/i18n

Then change the index.ts to :

import { Callback, Context, Handler } from 'aws-lambda';
import i18n from 'i18n';
interface TriggerEvent {
lang: string;
}
export const handler: Handler<TriggerEvent, string> = (event: TriggerEvent, context: Context, callback: Callback<string>) => {
// init i18n
i18n.configure({
defaultLocale: 'en',
directory: __dirname + '/locales',
});
// set locale according to event
i18n.setLocale(event.lang);
// return the translation
callback(null, i18n.__('title'));
};

Compile locally and test it:

npm run tsc && amplify mock function translate

You should see the result :

You can change the lang in the event.json to "lang":"en" and after launch again npm run tsc && amplify mock function translate you should see:

Publish the function, by adding at the root folder this to your package.json

...
"scripts": {
...
"amplify:translate": "cd amplify/backend/function/translate/ts && npm install && npm run tsc && cd -"
...
}
...

Then push it:

amplify push

As you can see, now we have package.json , localesand node_modules folders in our lambda, but we kept it small and simple.

Remove and clean all in AWS

amplify delete

BONUS

Hide compile .js files

If you want to hide the file from your VS Code go to .vscode/settings.json and add the following:

...  
"files.exclude": {
"amplify/backend/function/**/*.js": true
},
...

And also add in the src folder a .gitignore file with

*.js

Library aws-sdk

If you needaws-sdk , you can add it to the package.json in the src folder in the dev dependencies only, as it will be included automatically in our AWS Lambda when deployed. You don't need to add it in the prod dependencies. In the ts folder you can also add it in the dev dependencies.

--

--

Vincent Delacourt

Interesting in start-up or project development in the latest technologies for web and mobile apps