# Typescript Support

xpresserTs is the Typescript implementation of xpresserJs.

Xpresser was written with typescript but was not built for Typescript when it first started, we had to focus on making it lovely for javascript first. Now this has been achieved, we have given xpresser the full Typescript supports it needs.

  • Use .ts files
  • xjs-cli creates typed .ts files
  • Provide support .ts.hbs factory files.
  • Provide option for node or typescript environments.

# Creating a Project

Creating a new xpresserTs project is no different from running the usual xjs new command and select Typescript using xjs-cli or starting in a plain app.ts file if you have a good understanding of the xpresser framework

# Using xjs-cli

Note: xjs-cli version must be >=0.1.39, any lower version will not have the option for Typescript

xjs new xpresser-ts-app

# Plain app.ts file

import {init} from "xpresser";

const $ = xpresser.init({/* configurations */})

// This line is required for all xpresser typescript projects
$.initializeTypescript(__filename);

// Boot Xpresser
$.boot();

# initializeTypescript?

This method does a little magic behind the scenes using the __filename argument passed to it.

# Why __filename?

xpresser not only being a web server framework but also a cli framework needs to know what file type you are running. if it detects a .ts extension it means the app is running in typescript mode and vice versa when it detects a .js file extension, this helps xpresser decide if to create .ts files when you use the xjs make:* command.

# Why would it detect .js when using Typescript?

When you compile Typescript to Javascript files which is required for production because nodejs only understands node Javascript syntax, the extension of __filename becomes .js when you run it.

This concept makes it possible for the initializeTypescript function to provide an option where you can choose what to run when in .js/.ts mode as it's second argument.

# Usage

# initializeTypescript(filename: string, run?: (isNode) => void)

$.initializeTypescript(__filename, (isNode: isNode) => {
    if (isNode) {
        // This will log only when running built .js files.
        $.logInfo('Running built .js version');
    }
})
  • filename: must be __filename #why __filename?
  • run a function where you run codes for different modes. i.e .js/.ts
  • isNode: is false when in typescript mode but holds type isNode (opens new window) data when in Nodejs mode.

# isNode

In Nodejs mode isNode returns an object.

type isNode = {
    ts: {
        baseFolder: string
    }
} | false

The ts.baseFolder holds the guessed path to your typescript directory. The term guessed path is used because it was guessed assuming that yourtsc build folder and xpresser boot file are in same directory, which is 90% the use case.

/my-app:
    - backend
    - build
        -- backend
        -- server.js
    - node_modules
    - server.ts # Boot file
    - package.json

With this file structure when you run build/server.js the ts.baseFolder will be /my-app

# isNode Use Cases?

This depends on your project, but we have encountered many use cases for this option. It started with a situation where routes file remains routes.ts after build because the value comes from the config {paths.routesFile}.

initializeTypescript behind the scenes when in node mode checks if your routesFile config has a .ts extension and renames it to .js i.e setting it to the compiled routes file path.

# Import type files

Version >=0.4.0 of xpresser ships with default type files (*d.ts) that should be imported to your project and added to your tsconfig.json using the command below.

xjs import xpresser types

The following files will be imported to your backend/types folder.

- index.d.ts  
- modules.d.ts  
- xpresser.d.ts  

Add to your tsconfig.json

{
  "compilerOptions": {
    "types": [
      "./backend/types"
    ]
  }
}

# index.d.ts

This is the index file where other required types should be imported/referenced.
Note: We recommend you don't declare types here, only make reference to other declaration files.

# modules.d.ts

In Typescript, when you require a module that doesn't have types you are required to declare these modules yourself depending on your strict settings. e.g:

declare module "express-edge";

module.d.ts gives you a private space to declare these modules.

# xpresser.d.ts

All declarations related to extending xpresser, or any of it's plugins should be declared here. For example extending the DollarSign or http key in controller actions.

# Types you should know

Below are common Types you should know.

# $ (DollarSign)

import {DollarSign} from "xpresser/types";

declare const $: DollarSign;

// Now you can access the global `$`
$.helpers.randomStr(10) // 10 random alphabets

# Http

This represents the http variable your controller actions receives as first argument. it also carries two types Request&Response

  • http: Http
  • http.req: Http.Request
  • http.res: Http.Response
import {Http} from "xpresser/types/http";

export = {

    404(http: Http): Http.Response {

        http.res.status(404); // Set Response Status

        return http.send({
            url: http.req.url // Current Url
        })
    },
}

# What next?

Now you have known what typescript brings to the table, you can continue using xpresser the same way you know how to but with Typescript support.