How to import other types into my TypeScript custom declarations file? How to import other types into my TypeScript custom declarations file? reactjs reactjs

How to import other types into my TypeScript custom declarations file?


If we would like to declare that the global.mountWithContext function exists and has the indicated type we can add the following to an empty declaration file in our project.

import React from 'react';import enzyme from 'enzyme';declare global {  namespace NodeJS {    interface Global {      mountWithContext<P, S>(node: React.ReactElement<any>): enzyme.ReactWrapper<P, S>;    }  }}

Details

Here is a break down each of the constructs in the above:

  1. The declare global block: The purpose of this construct is to modify, to augment if you will, the global scope, either by introducing new declarations or by modifying existing ones, from within a non global context such as a module. Our declaration file is a module because it contains a top-level import clause that imports ReactWrapper from Enzyme. Such a block is called a "Global Augmentation" and may appear in implementation files as well.

  2. The interface Global wrapped in the namespace NodeJS structuring: In our tests we are accessing the mountWithContext function as a member of the global variable, incidentally named global, that is provided by the Node environment. This variable is already declared by the type declarations for Node at the same level as other environmental globals such as process. However, we need to augment its type, by adding a new member. The type of this global global is the interface Global already declared inside the namespace NodeJS, by the official declarations for Node. We accomplish this by declaring a new member of the interface Global. Our augmentation needs to be wrapped in the namespace containing Global or else it would be considered a separate interface. Roughly speaking, lexical scoping applies. (recall that TypeScript interfaces can be declared multiple times in the same scope and that these declarations will be merged)

Notes

Where do we place this declaration?Anywhere that will cause TypeScript to pick it up and include it in our compilation context.By convention we will place it in a file named globals.d.ts in the root directory of our project. (Technically it can be named something else and go in a lower directory).

It is important to note that this declaration file is part of our application code and should be checked into source control.It must not be placed alongside third party declarations in directories such as typings, node_modules/@types, or jspm_packages/npm/@types.

It is also important to note that this augmentation affects TypeScript files (.ts, .tsx, .d.ts) only. If we were rather declaring this function to be picked up by the TypeScript language service simply to provide intellisense when working in .js or .jsx, files, this approach will not work.


The function signature is wrong, you have to declare the generic types first, for example:

function foo(T: bar): T // wrongfunction foo<T>(T: bar): T // rightfunction foo<T extends K, K>(T: bar): K // right

In your case something like this should work:

declare function mountWithContext<P, S>(node: React.ReactElement<any>): ReactWrapper<P, S>;

If you happened to know what P and S are about you can be more specific, using <P extends React.Component, K>, for example.