Installing TypeScript
yarn add --dev typescript
npm i typescript --save-dev
Now you can use the TypeScript compiler running tsc
. To test whether a TypeScript file compiles create a simple file:
const name = "Mathias"; console.log(name);
and then run tsc index.ts
.
You thought it was as simple as that but you end up with an error:
.../node_modules/typescript/lib/lib.dom.d.ts:19620:15 19620 declare const name: void; ~~~~ 'name' was also declared here.
The reason is that name
is already defined on the window
object (global scope), so you either have to change your variable name or preferably make your file a module by adding export{}
to compile without errors:
const name = "Mathias"; console.log(name); export {}
Now it works. Let’s create another module other.ts
and import it into index.ts
to see how the compiler behaves. Will it compile all TS files to one single JS file or into two JS files?
import sayHello from "./other"; const name = 'Mathias'; console.log(sayHello(name)); export {};
function sayHello(name: string) { console.log(`Hello ${name}`); } export default sayHello;
Executing tsc .\src\index.ts
shows that TypeScript creates two js files, index.js
and other.js
.
Can I bundle my TS files into one JS file?
It is okay to compile many TS files into many JS files for a NodeJS project, but for a web front-end project we would rather like to have a single bundled file that we could load in the browser. Can that be done with TypeScript only? Yes, but with restrictions: You can use the compilerOption outFile
to concatenate and emit output to a single file, but outFile
cannot be used unless module
is None
, System
, or AMD
. That means, that this option cannot be used to bundle CommonJS or ES6 modules. For that to work, we need a bundler like Webpack.
How can I compile my TS files without specifying everything on the command line?
It is impractical to run tsc index.ts
every time we change code. We could use TypeScript’s watch mode with tsc -w index.ts
instead, but there is a better way. We define all our compile options once in a tsconfig.json
and from now on simply run tsc
or tsc -w
without specifying any other parameters.
Configuring TypeScript using tsconfig.json
Run tsc --init
to create a tsconfig.json
in your project root. Inspecting the file, you can see that there are many options, most of them commented out.
How should I adjust tsconfig.json?
Here are just a few of the more important config properties:
- You want all your TS files within
src
folder compiled? Add theinclude
property - You want compilation output to a specific folder? Use
outDir
compiler option - You want to generate sourceMap files for better debugging? Use
sourceMap: true
- In some places, TypeScript doesn’t try to infer any types for us and instead falls back to the most lenient type called
any
. This defeats the purpose of using TypeScript in the first place, so you should setnoImplicitAny: true
. strictNullChecks: true
makes handlingnull
andundefined
more explicit, and spares us from worrying about whether we forgot to handlenull
andundefined
Here is an example config file:
{ "compilerOptions": { "module": "commonjs", "esModuleInterop": true, "target": "es6", "noImplicitAny": true, "moduleResolution": "node", "sourceMap": true, "outDir": "dist", "baseUrl": ".", "paths": { "*": [ "node_modules/*", "src/types/*" ] } }, "include": [ "src/**/*" ] }
// src/index.ts const name = "Mathias"; console.log(name); export {}
Now, when running tsc
in your project root folder, your ts files under /src
will be compiled into a /dist
folder, including source maps. You can run tsc -w
to watch for file changes and automatically compile changed files.
Option to use import type
With the following option any import that is just a type will be imported as import type
instead of import
. This also works with auto import of IDEs.
"compilerOptions": { "importsNotUsedAsValues":"error", // ... }