With the raising of TypeScript, we decide to move our code from JS + Flow to TypeScript. Being with Flow we’ve found lots of benefits from strict typing, it helps us eliminates bugs before they are born, additionally tooling around TS is also growing rapidly(VSCode + TS is an amazing experience), so it seems the right time to embrace TS.

Basically, you can see the journey as two parts, part 1 you rewrite your code to TypeScript, this isn’t that painful since we’ve been on Flow for some time, Flow is very much like TypeScript, so it’s just a matter of spending time fixing the syntax errors and type errors that tsc doesn’t like. Part 2 is to configure the other cogs play smoothly with TypeScript, this is the part can make dudes smash their keyboards.

We use Serverless framework to manage our lambda functions, and serverless-webpack + Babel to transpile TS code to JS code that Lambda runtime (NodeJS 8.10) is happy with.

#Part of serverless.yml custom:

webpack:

webpackConfig: webpack.config.js

packager: 'yarn'

Webpack.config.js

As you can see we use babel-loader instead of ts-loader , there is no particular reason, but you need to be on Babel 7 with @babel/preset-env and @babel/typescript . If you decide to use ts-loader make sure you have transpileOnly: true, this will let ts-loader do the transpile job but not type checking, normally the type checking process should be part of your CI testing tasks, here it should only deal with transpile to JS and push to Lambda.

For @babel/preset-env , targets is set to node: true, because the transpiled JS code is for Lambda NodeJS runtime, no need to worry about all the different browsers, how good is that!

One more thing to notice, the output.filename needs to be [name].js, this will name the transpiled JS code the same as the source TS code, this is because in your serverless.yml, you probably have something like

functions:

your-function:

handler: my/lambda/functions/in-ts/hello.world

....

This tells the offline simulator the function is located at my/lambda/functions/in-ts, the file name is hello.js. If webpack is configured to output the file to [name]-bundle.js, then you should change it to my/lambda/functions/in-ts/hello-bundle.world.

As mentioned above, Babel does not validate your typings, it simply strips out all the TypeScript, turns it into whatever JS you want, hence it’s faster than tsc . But you do need to validate the typing before Babel kicks in, so with tsconfig.js and run tsc you get the checking. In your tsconfig.json , make sure you have “noEmit”: true, this will tell tsc to not transpile because we have babel-node does the job.

Last but not least, don’t be confused by .babelrc and tsconfig.json, Babel looks at .babelrc and doesn’t care tsconfig.json, tsc looks only at tsconfig.json and doesn’t care .babelrc.

Like I said in the beginning, tooling around TypeScript moves fast, what is working today may change tomorrow, so don’t smash your keyboard if things don’t work, just be patient and keep trying.