Looking for how to fix
parameter 'req' implicitly has an 'any' type
? (or something similar) Read This!
In my previous article, we learned how to get started with Express.js in 5 minutes. Today, I am going to show you how to convert a JavaScript Express.js project to TypeScript.
If you enjoy this article give me a follow on Twitter to read all of my latest software development content!
Pro Tip
3 Reasons to Use TypeScript.
- TypeScript is much easier to read and debug.
- TypeScript makes you much more productive with the help of IDE's such as VS Code
- If you know JavaScript you already know TypeScript!
TLDR: Here is the fulling working code on my Github.
Install & Configure TypeScript
Let's get started. Please refer to my previous post as a starting point for this article. First, you will need to install the TypeScript compiler via npm
.
npm install --save-dev typescript
Next, we need to add a file to tell TypeScript how to compile (transcompile) your TypeScript code into native JavaScript. This is needed because JavaScript environments (browsers) only understand... well, JavaScript. Let's add a tsconfig.json
file to the root of the project.
nano tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": [
"node_modules/*"
]
}
},
"include": [
"src/**/*"
]
}
A couple of notes on this configuration:
module
- We are usingcommonjs
here. This is the module system that Node.js uses.target
- We are targeting the ES6(ES2015) standard which is compatible with modern versions of Node.js.include
- The TypeScript compiler will try to compile any TypeScript files ending in.ts
it finds in thesrc
.outDir
- The folder where compiled JavaScript gets saved, in this case,dist
. This is a common folder name for this use case.
Install & Configure TSLint
Now we are going to install a linting tool. This is a static code analysis instrument used to find problems in your code while you write it. Also, it can be used to keep styles (tabs/indentations) consistent in a project. We will be using TSLint for this demo.
First, we need to install tslint
as a dev dependency. This means that it is only used when you are writing code. It will not be included when you build the project for production deployment. This yields smaller builds with fewer security concerns.
npm install --save-dev tslint
Next, we will create a tslint.json
file to instruct tslint
how to lint
our project.
nano tslint.json
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {},
"rules": {
"trailing-comma": [ false ]
},
"rulesDirectory": []
}
A couple of notes on this configuration:
defaultSeverity
- This is the default severity level applied to the configured rules.extends
- We are going to extend the recommendedtslint
rules.rules
- We are adding a custom rule here to not allow trailing commas.
Update NPM Configuration
Now that we have TypeScript and TSLint installed and configured, we need to update package.json
to tell node how to build the project with TypeScript.
nano package.json
"main": "dist/index.js",
"scripts": {
"prebuild": "tslint -c tslint.json -p tsconfig.json --fix",
"build": "tsc",
"prestart": "npm run build",
"start": "node .",
"test": "echo \"Error: no test specified\" && exit 1"
},
A couple of notes on the changes:
main
- This now points to the compiled JavaScript file inside of thedist
folderprebuild
- Before we build the project we are going tolint
the project.-c
- This passes a configuration file totslint
-p
- This passes a TypeScript config file totslint
--fix
- This flag is used to fix linting errors for the selected rules, this may overwrite linted filesbuild
- Thetsc
command will compile your project. If you want to compile your JavaScript files without starting the project you can runnpm run build
Lastly, we need to change our single JavaScript file to TypeScript! You simply need to change the file from .js
to .ts
.
cd src
mv index.js index.ts
Start your servers!
Time to start our new TypeScript project!
cd ..
npm run start
Oh no! The project no longer compiles!
ERROR: 1:17 no-var-requires require statement not part of an import statement
ERROR: 12:4 no-console Calls to 'console.log' are not allowed.
ERROR: 6:17 - error TS7006: Parameter 'req' implicitly has an 'any' type.
ERROR: 6:22 - error TS7006: Parameter 'res' implicitly has an 'any' type.
There are three main issues we need to address with the original code we wrote. TSLint does not consider using console.log
production-ready code. Therefore, we will need to add some syntactical sugar to tell TSLint to ignore this error.
app.listen( port, () => {
// tslint:disable-next-line:no-console
console.log( `server started at http://localhost:${ port }` );
} );
Second, when using TypeScript you should use import
instead of require
. Therefore, we just need to change a line of code from:
const express = require( "express" );
to
import express from "express";
Third, the TSLint also does not like using the any
parameter type. If you do not declare a type for a parameter it is implicitly any
. It's a best practice to use types
, it is called TypeScript! A simple fix for this is to add some well-known type declaration files for node and express. Since we are using the express library any callback functions should have types associated with them.
npm install --save-dev @types/node @types/express
Start your servers! (Take 2)
Finally, start up your project and you should be good to go this time around!
npm run start
Conclusion
It is very straightforward to get started with TypeScript, and I highly recommend it. You will be able to take advantage of tools that make you more efficient and will produce fewer errors, a win-win! Here is the fulling working code on my Github
Caveats
TSLint is currently deprecated. I purposely used it here so I can write a future post on how to migrate TSLint to ESLint. Keep an eye out for the updated post! I will add a link in the future.
Resources
Use TypeScript to Build a Node API with Express
What Is Typescript and Why Use It