How to declare a type globally in a project (typescript)

In a typescript project, is there any way to declare a type and share it across all files, in the same way we have access to types defined globally at node.d.ts?

For example, let's say that in my project a IUser is something such as

interface IUser {
   name: string,
   mail: string
 }

Ok, I can create that interface in a common/interfaces.ts file and import it every time I need it... but would be so nice to be able to declare such interfaces globally for the whole project and have quick access to them without importing any file


You can create a definition file, ending with the .d.ts extension, and place it in your project where you'd like:

user.d.ts

interface IUser {
    name: string,
    mail: string
}

This is also a good way to fill missing global types. I have a lib/global folder per project to place these files.

This only works with type definitions, not actual code, as (1) that actual code would have to be imported some way, (2) .d.ts is ambient. Also, for types defined this way to be globally visible, the corresponding declaration file should not contain top-level exports (otherwise the declaration file will be regarded as a module, requiring an import to access its types).


You can also declare modules:

declare module "my-module" {
    export declare class Something {
        public something: number;
    }
}

And then TypeScript will allow the following:

import { Something } from "my-module";

You can define types in multiple files and use them in other files. There are two possble ways:

  1. The files are using the same namespace. In this case the type can be reused directly.
  2. The files are using different namespaces. In this case the reusable type has to be marked with export. It can then be used in other namespaces. With the import statement you can avoid having to use the namespace prefix.

In any case, you have to add a reference to the file whose types you want to reuse.

Same namespace

File 1:

namespace Example {
    export interface IUser {
       name: string,
       mail: string
    }
}

File 2:

/// <reference path="./File1.ts" />

namespace Example {
    class User implements IUser {
       name: string,
       mail: string
    }
}

Different namespaces

File 1:

namespace Example {
    export interface IUser {
       name: string,
       mail: string
    }
}

File 2 (no import):

/// <reference path="./File1.ts" />

class User implements Example.IUser {
   name: string,
   mail: string
}

File 2 (with import):

/// <reference path="./File1.ts" />

import IUser = Example.IUser;

class User implements IUser {
   name: string,
   mail: string
}

Create global.d.ts in your project root.

Here is an example of how to declare global types constants and interfaces that will be understood globally

//example import for externally loaded library
//this will not form part of the bundle but will allow typescript to understand external libraries throughout the project
import _ from 'lodash'; 

declare global { 
    //Example global constant for libraries served via webpack externals. example webpack config:: externals: { _: 'lodash' }
    //This assumes lodash was already load in DOM for example in <head> via CDN link before main.js is loaded.
    const _: typeof _; 

    //example of custom types
    type JSONPrimitive = string | number | boolean | null;
    type JSONValue = JSONPrimitive | JSONObject | JSONArray;
    type JSONObject = { [member: string]: JSONValue };

    //example of custom interface
    interface JSONArray extends Array<JSONValue> {}
}