Initializing Project
First of all initialize npm project:
npm init -y
Then install some typescript
, types for node.js
, linter and prettier:
npm install --save-dev typescript @types/node
Now initialize typescript
project:
npx tsc --init --rootDir src --outDir build --esModuleInterop --resolveJsonModule --lib es6 --module commonjs --allowJs false --noImplicitAny true
Some of important tsconfig.json
options:
rootDir
: This is wheretypescript
looks for source code. We've configured it to look in thesrc/
folder.outDir
: Where TypeScript puts compiled code. In our case it will be placed insidebuild/
folder.esModuleInterop
: If we're usingcommonjs
as a module system fornode.js
, then we need this to be set to betrue
.resolveJsonModule
: If we usejson
in this project, this option allowstypescript
to use it.lib
: This option adds ambient types to the project, allowing to rely on features from differentecmascript
versions, testing libraries or browserDOM
api.module
:commonjs
is the standardnode.js
module system.allowJs
: this option allows you to include.js
files among.ts
ones.noImplicitAny
: Intypescript
files, don't allow a type to not specify type. Every type needs to have a specific type or explicitly declareany
type.sourceMap
: Create type maps for better debug experience.-
strict
: Strict mode including strict null checking, strict functional types, check, thatbind
,call
andapply
match function's signature, check for not initialized constructor properties.
This should create roughly similar tsconfig.json
file:
{
"compilerOptions": {
"target": "es2016",
"lib": ["es6"],
"module": "commonjs",
"rootDir": "src",
"resolveJsonModule": true,
"allowJs": true,
"sourceMap": true,
"outDir": "build",
"removeComments": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"alwaysStrict": true,
"skipLibCheck": true
}
}
Some Additional tsconfig.json
Sections
Exclude:
exclude
section defines paths, which will be excluded from the compilation:
{
"exclude": [
"node_modules", // exclude node_modules. excluded by default if no `exclude` section specified
"path-to-file-or-folder-to-exclude",
"**/*.dev.ts" // exclude all files with specified extension in any folder
]
}
Include:
include
section works the same as exclude
but to include specified patterns into compilation.
Files:
files
section specifies concrete files to compile.
AllowJs && CheckJs:
allowJs
and checkJs
options enable support for js
validation inside of ts
projects.
Specifying Of Compiled Files Source And Destination:
outDir
value used to specify the destination folder of compiled *.ts
files.
rootDir
specifies the root of target files to compile. Only files from inside of this root will be compiled.
Other Options:
removeComments
- not include comments into compiled*.js
files.noEmit
- compile and check source files, but not create compiled*.js
files.noEmitOnError
- not emit compiledjs
when compilation error occurs.
Compilation
To compile created project run:
npx tsc #compile project
npx tsc -w #set compiler to watch mode; (--watch)
Running *.ts
file without compilation to js:
npm install --save-dev ts-node nodemon
npx tsc <file-name>.ts
With monitoring:
Create nodemon.json
:
{
"watch": ["src"],
"ext": ".ts,.js",
"ignore": [],
"exec": "ts-node ./src/index.ts"
}
And also let's add run configuration into package.json
:
"scripts": {
"start:dev": "nodemon"
}
Linting
First install eslint
package and some of it's supplement packages:
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
Create .eslintrc
file:
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
]
}
To ignore some files or folders like node_modules
during linting create .eslintignore
:
node_modules/
build/
**/*.js
Add lint script to package.json
scrypts:
"lint": "eslint . --ext .ts",
Additional Linting Configuration:
There are three modes for a rule in eslint
:
off
- 0warn
- 1error
- 2
There is a documentation on rules reference.
For example to restrict usage of console.log
:
"rules": {
"no-console": 2 // this will lead to displaying an error on console.log
}
Formatting
To format typescript
code we will use prettier
library:
Install it:
npm install --save-dev prettier
Then create prettier
configuration file - .prettierrc
in the root of the project:
{
"semi": true,
"trailingComma": "none",
"singleQuote": true,
"printWidth": 80
}
semi
set to true means thatprettier
will add semicolons when necessary.trailingComma
set to none means thatprettier
will remove any trailing commas at the end of objects.singleQuote
set to true means thatprettier
will automatically use single quotes instead of double quotes.printWidth
set to 80 specifies that the printer will wrap any lines that exceed 80 characters.
More prettier
rules
Add formatting command to package.json
scrypts:
"format": "prettier --config .prettierrc 'src/**/*.ts' --write"
Conflicts with ESLint:
There probably will be conflicts between prettier
formatting and and eslint
. To make these two love each other install:
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
eslint-config-prettier
: Turns off alleslint
rules that have the potential to interfere withprettier
rules.eslint-plugin-prettier
: Turnsprettier
rules intoeslint
rules.
Lastly, we need to make an adjustment to the .eslintrc
.
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "prettier"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {}
}
Testing
For tests we will use Jest
testing framework. To install it:
npm install --save-dev npm install --save-dev jest @types/jest ts-jest jest @types/jest ts-jest
And create a configuration file for jest
:
npx ts-jest config:init
Modify content so:
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
moduleNameMapper: {
"@exmpl/(.*)": "<rootDir>/src/$1",
},
testRegex: "((/__tests__/).*|(\\.|/)(test|spec))\\.(ts|js)$",
coverageDirectory: "coverage",
collectCoverageFrom: ["src/**/*.{ts}", "!src/**/*.d.ts"],
}
Here testRegex
allows to discover test files.
Add testing scripts to package.json
:
"test": "jest --coverage",
"test:watch": "jest --coverage --watchAll",
To use test discovery in Visual Studio Code
Jest Test Explorer
seems quite a good extension.