In the past few days, when I started to dig into ambient modules, I also come across the concept of TypeScript configuration. Obviously it’s not a new concept, but I’m still far from being mastering it. So I think it will be worth to have a separate blog discussing the popular configuration options — in
I put here 3 examples of tsconfig, and will go through the properties in each of them:
“lib”: [“es5”, “es6”, “es7”, “es2017”, “dom”],
“exclude”: [“**/*.spec.js”, “**/*.spec.ts”, “**/*.spec.tsx”, “**/*.stories.tsx” ]
By default, TypeScript compiles recursively searches for all files in the root directory. But this is not encouraged, since without constraint, when another project references yours, it would have to read and parse every file in the compilation to figure out where to find the .d.ts file for any particular input. It would also have to do this to see if the project was up-to-date or not
However, we can explicitly define where TS search for files, and this is through
window.d.ts has a top level import then the imported file will be compiled as well.
include & exlude
Instead of listing each file manually, we can use
include option to specify directories with file patterns. For example, we can include every
.ts file in folder
And we can do the same to exclude any file following a pattern using
exclude keyword as well.
Note that the priority for the 3 options above are
Files> exclude > include , meaning that the files listed in
files will be compiled even it’s excluded in
exclude option. And if it’s both listed in
include then it will be excluded.
Note that the pattern
**/* simply means all folder and any files with extensions
.tsx will be included.
If we want to transpile ES6 modules into a different module system: CommonJS, AMD, etc, we can use
module option. By default the
module transpiles to
To be able to use classes from the ES standard libraries in your TS sources, you should use
lib option and specify all standard ES libraries interfaces used in your sources. Note that some libraries are included by default like
ES6 , but when you specify
lib option you overwrite it, and need to manually define it again.
“lib”: [“es5”, “es6”, “es7”, “es2017”, “dom”]
In TS, modules are resolved differently based on whether the module reference is relative or non-relative. It will be set to
classic by default.
With node, if you have a relative import like
import moduleA from “./moduleA” in source file
/src/myComponent.ts, TS will look up declaration in paths like:
With a non-relative import like
import moduleA from “moduleA” in source file
/src/myComponent.ts, TS will look up paths like below in
Classic it’s much simpler. With relative import, TS will look for
With non-relative path import in a file
/src/components/app.ts, TS will look up files in paths:
baseUrl & paths
Note that when options is set to
node , TS looks up
node_modules folder for non relative module import. But it can happen that your imported module is in another folder, so you will need the flexibility to tell TS to look for other routes:
This is to tell TS for module
@myPackage/internal-components in src folder instead of node_modules folder. TS will look for
dateJS.d.ts in src first and if not found, will look inside
src/dateJS directory. It will first try to locate
package.json file with
typings property specifying the main file, and if not found will default to
In order to incliude any modules not only dateJS, using asterisk wildcard like below and when you reference modules do something like “
import ModuleA from src/ModuleA
"src/*" //* maps any files under src.
declaration & declarationDir
There are time when we need to create ambient files to add declaration for a 3rd party libraries or any imported assets without declarations. You will most likely need to generate and consume declaration files yourself. But sometimes especially when you want to publish your NPM package, you should include the
.js and the
.d.ts files - and not the
declaration comes handy
What this do is to instruct the TS compiler to output declaration files
Sometimes it is convenient to output declaration files into one place (the
types folder )using
declarationDir option and put into one file together:
typeRoots is specified, TypeScript will only look for declaration files defined in the path of
"./node_modules/@types",//include this otherwise will
//overwrite default behaviour
allowSyntheticDefaultImports is set to
true, you no longer need to include * in import.
So instead of
import * as moduelA from "moduleA" , you can write
import moduleA from "moduleA" .
esModuleInterop is set to
true , you don’t need to use the old
require keyword to import libraries .
There is a lot more to explore other than what is listed above, when I put more focus on compilation, but checkout for full list of configuration here in the documentation.