This is the new documentation of Custom Applications. You can still visit the legacy documentation during the migration from Project-level Custom Applications.

BETA

TypeScript support in Custom Applications

In the previous sections we learned all the major aspects of developing a Custom Application.

The purpose of this section is to learn how to use TypeScript in Custom Applications.

First we will learn what TypeScript is and what benefits it can bring us. Then, we will set up our Custom Application to work with TypeScript files. Finally, we will go over steps to prepare a sound migration plan to fully take advantage of TypeScript features.

Note that Custom Applications in JavaScript are fully functional and porting them to TypeScript is entirely optional.

If you find TypeScript not beneficial for your Custom Application, you can skip to the next section.

TypeScript: optional static typing for JavaScript

TypeScript is a superset of JavaScript: JS syntax is therefore valid TS. The goal of TypeScript is to help detect errors in code without running it and make development more efficient. Another considerable benefit is enabling a richer IntelliSense within IDEs for a great developer experience. It enables, for example, spotting common mistakes as you type the code, intelligent code completion and hover info.

TypeScript compiler checks your code and produces the equivalent plain JavaScript code without the type information for browsers to run.

Why TypeScript?

TypeScript's main advantages are:

  • compile-time error checking
  • code readability and self-documentation
  • great developer experience due to rich IntelliSense support
  • availability of new JavaScript features without current browser support.

TypeScript also has some disadvantages:

  • considerable learning curve
  • more code to write and maintain
  • certain TypeScript features (for example types based on generics) can lead to over-engineered code bases.

In the end, the decision regarding the adoption of TypeScript must be well-thought-out.

Creating a Custom Application in TypeScript from scratch

You can create a new Custom Application in TypeScript using the starter-typescript template. The template can be installed using the npx command. Replace <folder_name> with the name of the folder where the template should be installed into.

$ npx @commercetools-frontend/create-mc-app <folder_name> --template starter-typescript

Adding TypeScript support to an existing Custom Application in JavaScript

Certain configuration steps are required for enabling TypeScript support in Custom Applications:

TypeScript configuration

The tsconfig.json file is required to work with TypeScript. It enables numerous configuration options. To simplify the initial setup we provide a base tsconfig-mc-app.json file in the @commercetools-frontend/application-config package to extend from in your Custom Application.

Installation

yarn add @commercetools-frontend/application-config
# or
npm --save install @commercetools-frontend/application-config

Usage

Create a tsconfig.json file in the root directory of your application and add the contents:

{
"extends": "@commercetools-frontend/application-config/tsconfig-mc-app.json"
}

tsconfig.json is easily extensible and allows to create your custom configurations.

To compile TypeScript files to JavaScript files Babel (since version 7) or tsc CLI can be used, but there are certain differences to take into account.

Custom Applications are preconfigured to use Babel compilation to TypeScript.

tsc CLI is only used as a type checking tool, for example, run as yarn typecheck script:

package.jsonjson
{
"scripts": {
...
"typecheck": "tsc --noEmit"
}
}

Prettier configuration

To enable code formatting while typing TypeScript code edit .prettierrc configuration file:

.prettierrcjson
{
...
"parser": "typescript"
}

To run prettier as a script add the following contents to your package.json:

package.jsonjson
{
"scripts": {
...
"format:js": "prettier --write '**/*.{js,ts,tsx}'"
}
}

ESLint configuration

Custom Applications are preconfigured to lint TypeScript files with ESLint.

To make sure that ESLint configuration is set properly check if .eslintrc.js extends @commercetools-frontend/eslint-config-mc-app, and that the package is listed as the application dependency in package.json.

To run ESLint as a script, edit the contents of the jest.eslint.config.js configuration file in the root folder of the application:

jest.eslint.config.jsJavaScript
module.exports = {
...
moduleFileExtensions: ['js', 'ts', 'tsx'],
testMatch: ['<rootDir>/**/*.js', '<rootDir>/**/*.ts', '<rootDir>/**/*.tsx'],
};

To run ESLint run the following script from your package.json:

package.jsonjson
{
"scripts": {
...
"lint": "jest --config jest.eslint.config.js"
}
}

Jest configuration

For enabling Jest-based tests in TypeScript @commercetools-frontend/jest-preset-mc-app must be installed as a dependency and configured as below in the jest.test.config.js file in the root folder of the application:

jest.test.config.jsJavaScript
module.exports = {
preset: '@commercetools-frontend/jest-preset-mc-app/typescript',
};

Make sure the config file is passed to jest:

package.jsonjson
{
"scripts": {
...
"test": "jest --config jest.test.config.js"
}
}

Migrating the Custom Application codebase to TypeScript

Migration of an extensive codebase to TypeScript can be a strenuous task. It should be carefully considered and planned. TypeScript documentation can help with setting up a basic plan.

Two key recommendations for a successful migration:

  • refrain from introducing functional changes at the same time
  • ensure test coverage is sufficient before the migration to confidently progress without regressions

Please mind that with the recommended tsconfig.json configuration any type checking errors will not prevent the compilation, so don't be discouraged by the missing types as the application remains functional.

If the recommended configuration seems too strict to start with it might be loosen up by, for example, allowing explicit any type. In such case edit tsconfig.json:

tsconfig.jsonjson
{
"extends": "@commercetools-frontend/application-config/tsconfig-mc-app.json",
"compilerOptions": {
"noExplicitAny": false,
"strict": false
}
}

Additionally, edit ESLint config file .eslintrc.js:

.eslintrc.jsJavaScript
module.exports = {
extends: ['@commercetools-frontend/eslint-config-mc-app'],
rules: {
...
'@typescript-eslint/no-explicit-any': 'off'
},
};

We advice not to make this change permanent as any type does not provide type safety.