This GitHub repo accompanies a blog post which describes the tooling ecosystem for TypeScript. This repo provides the technical details in a concise form to accompany the more discussive blog post.
TypeScript is often run on the node.js
runtime which can be installed from here. On Windows this
is quick and straightforward but is followed by a lengthy install process for Visual Studio build tools, the chocolatey package manager and Python.
Once node.js
has been installed, then TypeScript is then installed globally with:
npm install typescript --g
However, for the purposes of this project we will make a project-level installation using the --save-dev
flag.
npm install typescript --save-dev
It is worth noting here that most "getting started" guides are based on a global install and thus will not work without modifying paths for tsc
and other tools if a project-level installation is done. Microsoft Visual Code finds project-level installed tools automatically.
Given this project-level installation then your programme is then compiled with:
./node_modules/typescript/.bin/tsc hello_world.ts
By default this will produce a compiled hello_world.js
file which sits alongside the TypeScript source code file.
The compiled code can then be run with:
node hello_world.js
The tsc
compiler is configured using a tsconfig.json
file, a template for which can be produced using the command:
tsc --init
TypeScript package management is typically done using the npm
package manager, installed with node.js.
npm init
will produce a package.json
file based on your responses to requests for metadata which describes your package.
Subsequently installing further packages, such as typescript
using the --save-dev
will create a a node_modules directory, a package-lock.json
file and will update the package.json
file. package-lock.json
is a description of exactly what is installed and should be committed to source control.
The virtual environment for TypeScript is largely determined by the local copy of the dependencies. The node version can also be set in
the package.json
:
"engines": {
"node": ">18.0.0"
}
npm has a neat feature whereby command line invocations of tools can be specified in package.json
and invoked with npm run {invocation-name}
. For this project the scripts
section looks like this:
"scripts": {
"test": ".\\node_modules\\.bin\\jest --watch",
"compile": ".\\node_modules\\.bin\\tsc",
"lint": ".\\node_modules\\.bin\\eslint src tests",
"prettier-check": ".\\node_modules\\.bin\\prettier . --check",
"prettier-fix": ".\\node_modules\\.bin\\prettier . --write",
"make-docs": ".\\node_modules\\.bin\\typedoc --out docs src/maths_funcs.ts"
},
The tools used in this set of invocations will be described below.
The package.json
file sits in the root of the project with a node_module
directory sitting underneath that. Based on this Microsoft example starter project suggests the following sub-directories:
src
- to contain project source TypeScript filesdist
- to contain compiled JavaScript files, this needs to be specified in theoutDir
key of thetsconfig.json
filetests
- to contain project test TypeScript filesdocs
- to contain generated HTML documentation files from TypeDoc.
The root of the project also contains configuration files for other tools used in the project (tsc
, jest
, eslint
, and prettier
). These tools can be configured in multiple ways, here it is done with json
format files although their contents could be added under their own keys to the package.json
file except for tsc
which uses the separate tsconfig.json
file.
Testing in this project is using the Jest library, installed with:
npm install jest ts-jest @types/jest --save-dev
Tests are put in the tests
directory and run with:
npm run test
This works because we made a test
entry in the package.json
file. Jest
is configured using a
file in the root of the project, here it is jest.config.json
which reads:
{
"transform": { "^.+\\.ts?$": "ts-jest" },
"testEnvironment": "node",
"testRegex": "/tests/.*\\.(test|spec)?\\.(ts|tsx)$",
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"]
}
It is possible to configure Jest
in the package.json
file, a JavaScript file or a TypeScript file. I chose a separate JSON file
because for an example it is clearer and I prefer configuration to be data rather than executable.
This project uses eslint for static analysis and prettier for formatting.
For TypeScript eslint
is installed with:
npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint typescript
In common with jest
there are multiple ways of providing configuration. In this project it is done with the .eslintrc.json
file:
{
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"root": true
}
Linting is run with:
npm run lint
prettier
is installed with:
npm install --save-dev prettier
The prettier
formatter has the same philosophy as the Python black
formatter which is to say it is opinionated and so I decided
to do no additional configuration. An ignore pattern is included in the .prettierignore
file to exclude the compiled JavaScript files
and :
# Ignore artifacts:
dist
node_modules
Two prettier
scripts are used, the first simply checks files:
npm run prettier-check
The second will re-write files:
npm run prettier-fix
Documentation for this project is by TypeDoc which is installed with:
npm install typedoc --save-dev
It is invoked with the following which is defined by the "scripts" entry
npm run make-docs
As a personal choice, I use Visual Studio Code. For this project I installed the eslint extension, the jest extension, and the prettier extension.
The TypeScipt support is built in to Visual Studio Code. The configuration for Code is found in the .vscode
directory of this repo.
This library implements a simple word count function. It is compiled with
npm run compile
And run with:
node dist/src/index.js tests/fixtures/file_for_word_count_test.txt