3

Context: I am trying to create a definition file for a library that I am not the author. When consuming the definition file I created, TypeScript mention it cannot find the definition file.

I have tried several things, here are the last three:

First try (inspired by a similar library d.ts):

declare class MessageFormat {
    constructor(message: string);

    compile: (messageSource: string) => Msg;

}
export type Msg = (params: {}) => string;
export default MessageFormat;

Could not find a declaration file for module 'messageformat'. 'node_modules/messageformat/lib/messageformat.js' implicitly has an 'any' type.

Second try (from TypeScript's example to write d.ts)

declare class MessageFormat {
    constructor(message: string);

    compile: (messageSource: string) => MessageFormat.Msg;

}
declare namespace MessageFormat {
    type Msg = (params: {}) => string;
}
export = MessageFormat;

Could not find a declaration file for module 'messageformat'. 'node_modules/messageformat/lib/messageformat.js' implicitly has an 'any' type.

Third try (from a GitHub question)

declare module "messageformat" {
    export type Msg = (params: {}) => string;
    export interface MessageFormat {
        new(message: string): any;
        compile: (messageSource: string) => Msg;
    }
}

Cannot use 'new' with an expression whose type lacks a call or construct signature.

Code: The three tentatives are in this repo: https://github.com/MrDesjardins/importdefinitionfiles

Can someone give me a pointer about what am I doing wrong?

8
  • 1
    How are you importing the module / trying to invoke new with it? Commented Apr 6, 2018 at 17:21
  • @RyanCavanaugh The third-party module is from npm and imported with import MessageFormat from "messageformat"; Commented Apr 6, 2018 at 17:25
  • Not sure why you suddenly switched to an interface with new(...) method in there in the last example. Changing that to class with a constructor is correct. Also, looking at the source the constructor signature should be: constructor(locale: string|string[]|Object) and the Object should be replaced with a proper interface as well. Commented Apr 9, 2018 at 9:17
  • Also, no need for export keywords in normal type definitions inside ambient module declarations. Everything is exported & declared by default. Commented Apr 9, 2018 at 9:22
  • The one export you do need at the end, since MessageFormat is the default export in this module is export = MessageFormat; Commented Apr 9, 2018 at 9:28

1 Answer 1

2

This works for me, inside some d.ts file in your project, filename is not relevant. DO make sure "messageformat" is the actual name of the node module, otherwise your packager will fail.

declare module "messageformat" {
    type Msg = (params: {}) => string;
    class MessageFormat {
        constructor(locale: string | string[] | Object);
        compile(messageSource: string): Msg;
    }
    export = MessageFormat;
}

Now, in some other module:

import MessageFormat from "messageformat";
const mf = new MessageFormat("en");
const thing = mf.compile("blarb");
Sign up to request clarification or add additional context in comments.

1 Comment

You are right, it works. I am a little bit confused about why the TypeScript's example on the official website doesn't have the module with quotes like this example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.