TypeScript for Enterprise Applications - Part 1

Template to build Node and TypeScript application from scratch.

·

4 min read

TypeScript for Enterprise Applications - Part 1

In this article, we will create a skeleton for a TypeScript project used in large-scale enterprises. It will include the following features:

  • Compiling TypeScript to JavaScript with a specified ECMAScript target.

  • Lint TypeScript to maintain consistency and detect errors during compile time.

  • Testing framework to test the application.

  • Docs for the code and apis

  • Changes in APIs


Volta

Volta is used for installing JS tools such as node and yarn. It also manages different versions of node, similar to other node version managers, allowing you to switch between projects without manually changing the node version.

To install Volta run command curl https://get.volta.sh | bash

To install node and yarn by using Volta run volta install node@lts yarn@^3.0.0

To start a new project

First, create a .gitignore file by running npx gitignore node.

To add a package.json file, run yarn init --yes. Then, make the necessary changes. To generate the old node_modules folder structure, use the command yarn config set nodeLinker node-modules to avoid self-reference symlink.

Make changes in package.json as shown below:

{
   "main": "dist/index.js",
   "types": "dist/index.d.ts",
   "scripts": {
     "build": "yarn tsc",
     "dev": "yarn build --watch --preserveWatchOutput",
     "lint": "yarn eslint src",
     "test": "yarn jest"
   },
   "license": "NOLICENSE"
 }

Pin the Node and Yarn versions (volta pin node@lts yarn@^3) to their desired versions using Volta. This way, when you switch to the project next time, it will use the correct versions of Node and Yarn.

//package.json
"volta": {
    "node": "20.13.1",
    "yarn": "3.8.2"
  },

TypeScript compiler and configuration

Install TypeScript as a devDependency to build the application:

yarn add -D typescript@5.4.5

To create a default tsconfig.json, run:

yarn tsc --init

Now, change a couple of options in tsconfig.json. The details of these options are available here.

//tsconfg.json
{
    "compilerOptions": {
        "target": "es2022", // use latest ES version to target
        "module": "commonjs", // node friendly node moduels 
        "declaration": true,
        "outDir": "dist",
        "stripInternal": true,
        "esModuleInterop": false,
        "skipLibCheck": false,
        "strict": true,
        "useUnknownInCatchVariables": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "exactOptionalPropertyTypes": true,
        "noImplicitReturns": true,
        "noUncheckedIndexedAccess": true,                
        "noImplicitOverride": true,
        "noPropertyAccessFromIndexSignature": true, 
    },
    "include": ["src", ".eslintrc.js"]
}

Make changes to the contents of the file src/index.ts.

/**
 * @packageDocumentation A small library for designing computer hardware through basic gates.
 */

import { Gate } from "./hardware/Gate"

/**
 * A class that represents a home.
 * @public
 */
export class SuperComputer {
  // this stores all parts
  #_gates:Gate[] = []

  /**
   * Creates a new instance of the Home class.
   */
  constructor() {
    this.#_gates = [new Gate({name: 'first', inputPins: ['a', 'b'], outputPins: ['d']} )]
  }

  /**
   * Gets the gates.
   */
  get gates() {
    return this.#_gates
  }

}

After running the command yarn build, which is yarn tsc, two files are generated: index.js and index.d.ts.


Linting

Now add linting and configure it for the project with these commands:

yarn add -D eslint

yarn eslint --init

After this, make changes to the eslint.config.mjs file.

import globals from "globals";
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";


export default [
  {
    languageOptions: {
      globals: {...globals.browser, ...globals.node},
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      }
    },
  },
  {
    files: ['tests/**/*.ts'],
    ...tseslint.configs.disableTypeChecked,
  },
  eslint.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
];

Run the yarn lint command, which is "yarn eslint 'src/**/*.{ts,tsx}'", to see linting errors.


Testing

Now we will add a test framework and supporting libraries.

yarn add -D jest @types/jest @babel/core @babel/preset-env @babel/preset-typescrip

// @filename: tests/index.test.ts
import { SuperComputer } from 'chips-cli'

describe('SuperComputer', () => {

  beforeEach(() => {
    superComputer = new SuperComputer()
  })

  it('should get me all gates', () => {
    expect(superComputer.gates()[0].getNames()).toBe('first')
  })
})
//tests/tsconfig.json
{
  "extends": "../tsconfig.json",
  "references": [{ "name": "chips-cli", "path": ".." }],
  "compilerOptions": {
    "types": ["jest"],
    "rootDir": ".."
  },
  "include": ["."]
}

API Report & Docs

For APIs and documentation, we will use Microsoft's api-extractor as our documentation tool.
yarn add -D @microsoft/api-extractor @microsoft/api-documenter

Then, create an api-extractor config file with the following command:
yarn api-extractor init

This will create a file /api-extractor.json. It contains the configuration for API documentation. Make the following changes. We will have different versions of the API, such as alpha and beta.
"alphaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-alpha.d.ts",

After running the following command, a file named chips-cli.api.md will be created inside the etc folder. It is a api-report.

yarn api-extractor run --local


API Docs

api-documenter is a command that creates markdown documents in the docs folder.
Run the following command:
yarn api-documenter markdown -i temp -o docs