Skip to content


Nick Devereaux edited this page Apr 6, 2021 · 11 revisions

Inherits from ClientGeneratorBase

The following code generates the TypeScript client code and DTO classes for a given Swagger specification:

var document = OpenApiDocument.FromUrl(swaggerSpecUrl);

var settings = new TypeScriptClientGeneratorSettings
	ClassName = "{controller}Client",

var generator = new TypeScriptClientGenerator(document, settings);
var code = generator.GenerateFile();


Available framework/library templates

The used template can be set via the Template property of the TypeScriptClientGeneratorSettings class.


Generates client classes which use JQuery for HTTP handling and simple callbacks for success and error handling.


Generates client classes which use JQuery for HTTP handling and JavaScript Promises to handle asynchronicity. Most modern browsers only support JavaScript ES5 which does not provide a native Promise implementation. You can choose from two promise types via the PromiseType setting:


Generates an AngularJS service class which uses the AngularJS http service.


The Angular template generates an Angular 2 service to access your backend.

More information about the Angular template


Warning: TypeScript v2.6.0 and v2.6.1 have a broken HeadersInit declaration, please use v2.6.2+ or earlier versions.

Template for the official window.fetch API with promises.

Required method on base class for UseTransformResultMethod:

transformResult(url: string, response: Response, processor: (response: Response) => Promise<any>): Promise<any> { 
    return processor(response);

Aurelia (based on Fetch)

Template for Aurelia using the HttpClient from aurelia-fetch-client. By using the HttpClient via dependency injection you can add global interceptors and other global configurations. When using a global response interceptor, beware that the generated TypeScript code calls the text() method to read the response. Because the response of a fetch call can only be read once, you cannot call arrayBuffer(), blob(), json(), text() or formData() on the response object yourself or the generated TypeScript code will throw an exception. If you need to read the response in your interceptor, you should clone the response first and perform the text() function or equivalent on the cloned Response (like this: response.clone().text()).

Sample project

Date and time handling

  • When generating DTO classes instead of interfaces, datetime values are automatically converted into a Date or MomentJS moment object.

Time span handling

  • When generating DTO classes instead of interfaces, TimeSpan values are automatically converted into a Date or MomentJS moment.Duration object. See Moment Durations.

    • A TimeSpan coming from a .Net Web API is formatted as string with the following format day.hours:minutes.seconds.milliseconds (ex: 7.23:59:59) in json. This format can be passed to moment.duration without change.
    • To send a moment.Duration back to the Web API we need to format it in the same manner again. But this isn't support by MomentJS and a plugin needs to be added. The import for this plugin has been added to NSwag generated TypeScript code. See import 'moment-duration-format';.

    Use the following script to install the plugin.

    npm install moment-duration-format
    npm install --save-dev @types/moment-duration-format

Extended classes and extension code

It is possible to extend the generated classes with own code. With this mechanism, you can add specific security code, caching or additional headers, new methods or properties. This works for client classes as well as the DTO classes. The external code is specified with the "ExtensionCode" setting. It accepts source code or a path to a .ts file (recommended).

Related Settings:

  • TypeScriptGeneratorSettings.ExtensionCode: The external code
  • TypeScriptGeneratorSettings.ExtendedClasses (requires extension code): The names of the extended classes
  • BaseClass (requires extension code): The base class of all generated client classes

Check out the NJsonSchema documentation for more information.

Extension code variables

In the ExtensionCode you can use the {clientClasses} variable which generates a mapping dictionary for all generated client classes. Note: ensure the placeholder is exactly as written without spaces. The output will look like:

{"PersonController": PersonController, "CompanyController": CompanyController}

When using the AngularJS template you can use this variable to register all generated client classes as AngularJS services. To do so, add the following code to your ExtensionCode:

var clientClasses = {clientClasses};
for (var clientClass in clientClasses) {
    if (clientClasses.hasOwnProperty(clientClass)) {
        angular.module('app').service(clientClass, ['$http', clientClasses[clientClass]]);

Extend client classes

You can extend generated classes by adding class names to the ExtendedClasses setting. The bodies of the extended classes are then copied into the generated classes. The external code can be defined in the "ExtensionCode" setting (the import of the generated classes must look as follows):

// Sample template: Angular2

import * as generated from "./apiClients";

class PersonsClient extends generated.PersonsClient {
    public myNewMethod() {


Transform the options or the result

You can customize the HTTP options or process each HTTP response. Use the settings "UseTransformOptionsMethod" or "UseTransformResultMethod" to enable the features. The then required "transformOptions" or "transformResult" methods can be implemented per client class ("ExtendedClasses" setting) or as a base class for all clients ("BaseClass" setting). The externally implemented "transformOptions(options)" method must return a promise which resolves to the transformed options (except for the JQuery templates, they require sync methods). The method parameters depend on the selected generator template (i.e. the used framework/library).

A sample for Angular 2 (the "BaseClass" setting is set to "ClientBase"):

// Sample template: Angular2

import * as generated from "./serviceClients";
import { RequestOptionsArgs } from '@angular/http'; // ignore

export class ClientBase {
    protected transformOptions(options: RequestOptionsArgs) {
        // TODO: Change options if required

        console.log("HTTP call, options: " + JSON.stringify(options));

        options.headers.append("myheader", "myvalue"); 
        return Promise.resolve(options);

    protected transformResult(url: string, response: Response, processor: (response: Response) => any) {
        // TODO: Return own result or throw exception to change default processing behavior, 
        // or call processor function to run the default processing logic

        console.log("Service call: " + url);
        return processor(response); 

Add a custom JSON.parse() reviver function

The Angular2, Fetch and Aurelia templates generate a protected jsonParseReviver field which is passed to all JSON.parse() calls. This reviver field can only be set with an extension class. To do so, add your client class to the ExtensionClasses array setting and implement the following ExtensionCode (sample for the Fetch template):

class GeoClient extends generated.GeoClientBase {
    constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
        super(baseUrl, http);

        this.jsonParseReviver = (key: string, value: any) => {
            return value; // TODO: Transform value if necessary

Inject an Authorization header

To inject a dynamic authorization header into the request use the following params in your nswag.json

  "codeGenerators": {
    "openApiToTypeScriptClient": {
      "clientBaseClass": "AuthorizedApiBase",
      "configurationClass": "IConfig",
      "extensionCode": "AuthorizedApiBase.ts",
      "useTransformOptionsMethod": true,

And provide the flowing typescript code

 * Configuration class needed in base class.
 * The config is provided to the API client at initialization time.
 * API clients inherit from #AuthorizedApiBase and provide the config.
export class IConfig {
   * Returns a valid value for the Authorization header.
   * Used to dynamically inject the current auth header.
  getAuthorization: () => 'the-authentication-token';

export class AuthorizedApiBase {
  private readonly config: IConfig;

  protected constructor(config: IConfig) {
    this.config = config;

  protected transformOptions = (options: RequestInit): Promise<RequestInit> => {
    options.headers = {
      Authorization: this.config.getAuthorization(),
    return Promise.resolve(options);

This is a working solution for Angular 9

export class AuthorizedApiBase {
  authToken = '';
  protected constructor() {
  setAuthToken(token: string) {
	  this.authToken = token;

  protected transformOptions(options: any): Promise<any> {
    options.headers = options.headers.append('authorization', `Bearer ${this.authToken}`);
    return Promise.resolve(options);