These are some quick notes on creating a new Typescript Node.js project that uses live development reloading with ts-node-dev and testing with Jest.

Setup Typescript

# Setup yarn package w/ default options
yarn init -y

# Add typescript deps
yarn add typescript ts-node-dev @types/node --dev

tsconfig.json

Add a tsconfig.json to configure the Typescript compiler. You can use yarn tsc --init to create a file with a list of all options. A simplified version that compiles all code in /src and outputs it to /build:

{
  "compilerOptions": {
    "esModuleInterop": false,
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "outDir": "build",
    "strict": true,
    "target": "es6"
  },
  "include": ["src/**/*"]
}

package.json scripts

Add a scripts section to package.json for development and building. Replace index.ts with the entry point:

"scripts": {
  "dev": "ts-node-dev --respawn  ./src/index.ts",
  "prod": "tsc --build && node ./build/index.js",
  "build": "tsc"
}

You can now start development mode using:

yarn run dev

Setup Jest for testing

# Install deps
yarn add jest @types/jest ts-jest --dev

# Create a default config file
yarn ts-jest config:init

Add a new script to package.json to run tests in watch mode:

"scripts": {
    "test" : "jest --watchAll"
}

Create a sample test in src. By default jest will look for files ending in .spec.ts or .test.ts, though this can be customized.

An example test:

import { doSomething } from "./index";

test('sample', () => {
  expect(doSomething()).toEqual(42);
});

Setup prettier

I use the Prettier VSCode extension for code formatting. Generally I don't like to think about formatting and have the VSCode set to auto-format on save:

// Inside vscode settings
"editor.formatOnSave": true,

To avoid auto-formatting causing problems when I'm working outside of my projects, I also require a .prettierrc file to be present in the project for formatting to work.

"prettier.requireConfig": true

An example .prettierrc file:

{
  "arrowParens": "avoid",
  "semi": true,
  "singleQuote": true,
  "printWidth": 80,
  "bracketSpacing": false
}