40

I'm using Moment.js to handle datetime objects in my TypeScript project. I would like to define an object type that has a key with a value of a type Moment.

However, when I add the following to a global definition file (test.d.ts), none of the interfaces in that file are found anywhere in the project.

import { Moment } from 'moment';

interface Test {
  date: Moment;
}

When I try to use the interface in a .ts or .tsx file I get this TypeScript error:

[at-loader] ./src/<examplefilename>.tsx:91:26 
    TS2304: Cannot find name 'Test'. 

Neither VSCode's TypeScript error checking nor TSLint show any problems with the code.

How can I import a type from an external module for use in a global definition file?

keawade
  • 403
  • 1
  • 5
  • 7
  • 1
    I would check tsconfig file. In compiler options - typeroots you should have @types path and the path to your typings – kimy82 Jul 31 '17 at 16:05
  • 1
    @kimy82, I don't think the issue is there. I can import moment just fine throughout my project but I am unable to import it in my project's `.d.ts` definition files to define a global type in my project that uses the `Moment` type. The rest of my `.d.ts` files are found without configuration and work as long as I don't try to import an external type. – keawade Jul 31 '17 at 16:41
  • Is the `d.ts` file with the global also included in your `tsconfig.json` project? – Matt Bierner Jul 31 '17 at 17:16
  • 2
    @MattBierner: Yes. The file and its interfaces are accessible across the project until I add the import statement. At that point the interfaces are no longer found by the compiler and I get the error I posted above. – keawade Jul 31 '17 at 18:11

3 Answers3

57

With TypeScript 3.3+ (and maybe since the 2.4 because it's the version that added support for dynamic imports), you have better ways to solve this isssue, using either:

interface Test {
  date: import('moment').Moment;
}

or

type Moment = import('moment').Moment;
interface Test {
  date: Moment;
}

with no need to export any interfaces ;)

Hugo Capocci
  • 671
  • 1
  • 5
  • 4
19

When file has top-level import or export statement it is considered as a module. All its' content (types, interfaces, etc.) you are interested in needs to be exported explicitly in that file and imported in those files that need the types.

// types.d.ts
import { Thingy } from 'sick-lib';

export declare interface IInterface {
  foo: any;
  bar: any;
  baz: Thingy;
}

// main.ts
import { IInterface } from 'types';

const xyz: IInterface = {
  foo: true,
  bar: false
};
Konstantin Vitkovsky
  • 1,198
  • 11
  • 15
  • 4
    That resolves the issue, thanks! It is a little frustrating to have to export all my interfaces manually now just because I imported one thing though. – keawade Jul 31 '17 at 18:49
  • 1
    if use export can remove the declare. `export interface IInterface ....` – Caal Saal VI May 16 '18 at 03:31
16

Here's an example of a global.d.ts file in a Create React App project:

declare type RouteProps = import("react-router-dom").RouteProps;

declare interface Xyz extends RouteProps {
  yada: string;
}
Wayne Bloss
  • 5,370
  • 7
  • 50
  • 81