Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot Load Custom Definition File in Repository #23185

Open
MrDesjardins opened this issue Apr 5, 2018 · 11 comments
Open

Cannot Load Custom Definition File in Repository #23185

MrDesjardins opened this issue Apr 5, 2018 · 11 comments
Labels
Domain: Error Messages The issue relates to error messaging Good First Issue Well scoped, documented and has the green light Help Wanted You can do this PursuitFellowship Help wanted from Pursuit fellowship; others please avoid until Dec 19 Suggestion An idea for TypeScript
Milestone

Comments

@MrDesjardins
Copy link

TypeScript Version: 2.8.1

Search Terms: Definition File, Ambient type
Detail
I am importing a JavaScript library that doesn't have any definition file. I want to create a custom definition file that I place in my repository. I want TypeScript to read this definition file.

I have tried many combination of tsconfig.json (typeRoot, include, path, baseUrl, etc.) Without being successful. I also moved the definition folder under src, and renamed the definition file to index.d.ts (inside a folder with the name of the library) without any success.

Code
Small complete repro here: https://github.com/MrDesjardins/importdefinitionfiles

// main.ts:
import MessageFormat from "messageformat"; // Doesn't have type
// messageformat.d.ts:
declare module messageformat {
    export type Msg = (params: {}) => string;
    export interface MessageFormat {
        new(message: string): any;
        compile: (messageSource: string) => Msg;
    }
}

Expected behavior: TypeScript to find the definition file and to use it without having a compilation error.

Actual behavior: Error message

Could not find a declaration file for module 'messageformat'. '/Users/pdesjardins/code/perso/importdefinitionfiles/node_modules/messageformat/lib/messageformat.js' implicitly has an 'any' type.
  Try `npm install @types/messageformat` if it exists or add a new declaration (.d.ts) file containing `declare module 'messageformat';`

1 import MessageFormat from "messageformat";

Playground Link: https://github.com/MrDesjardins/importdefinitionfiles

Related Issues:

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Apr 5, 2018

You need quotes around the name:

declare module 'messageformat' {

The error message tells you this:

> add a new declaration (.d.ts) file containing `declare module 'messageformat';`

In the future please use StackOverflow for questions.

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Apr 5, 2018
@MrDesjardins
Copy link
Author

MrDesjardins commented Apr 6, 2018

The compiler message is not clear. It was working on an empty module (as written in the error message) and I was fine, that is not the issue.

The issue is that I wanted to have a module defined, it makes sense to have the module without the quote. I support that statement because the compiler doesn't complain about the lack of quote. It works until an import. It is also intriguing that most types in the DefinitelyTyped repo don't contain the quote.

What doesn't work @RyanCavanaugh is that TypeScript mentions to " add a new declaration (.d.ts) " which I have. The error message guides the user in the wrong direction as if TypeScript couldn't find the definition file.

@RyanCavanaugh
Copy link
Member

declare module foo without quotes means something different from declare module "foo"; you have to write the one that you intend to mean.

@MrDesjardins
Copy link
Author

Thank you for your time Ryan.

Writing definition files from an external library in JavaScript is not straight forward. From many issues, questions and blogs, I can see many discrepancy in term of how to configure tsconfig to access a custom definition files as well as how to write them.

I honestly believe that the compiler message is not clear in my particular case, and I wish you could see that as a constructive feedback and see a potential improvement that can reduce the friction to use definition files in the future.

I am porting my question to Stack Overflow https://stackoverflow.com/questions/49697563/typescript-definition-file-cannot-find-d-ts

Best regards.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 6, 2018

So what would be your suggestion for a better error message?

@MrDesjardins
Copy link
Author

Hi Mohamed,

I suggest reformating the error message to be more accurate instead of being general. In my case, there is a definition file. I would remove the mention of adding a @types/ with NPM, and remove the mention to create a .d.ts. because it is already there.

Concerning clarity, for some time I wasn't sure if TypeScript was seeing the .d.ts I created. I goofed around the tsconfig.json with typeRoots, include, path. There is a general confusion about what is required and some quick search on Internet illustrate all different combination that people are trying. What I suggest is to make it very clear if TypeScript sees the definition file, sees it but doesn't understand the definition inside OR if it doesn't see it (then you can use the current error message and add that it cannot find it locally).

The definition file was compiling (no error) without the quote, however, it wasn't working hence there is something wrong by Ryan's comment. The message should mention why it needs quotes (which I do not yet know) and not compile if this is required. It still not clear to me why it's required.

In my actual case, I see two errors message:

  1. In the definition file mentioning that quote is necessary and giving the reason.
  2. In the consumption, instead of telling to add a .d.ts or node_nodule to say something about that TypeScript found a .d.ts (with path) however where is an issue with X because of Y.

Again, the goal here is to avoid people, like me with many years of TypeScript experience, having to bother the team.

Side note, the documentation around how to write definition file exists but has been written by people that are probably well aware of how definition file works. I haven't been able to be successful after more than one hour. As mentioned, I am far from being new to TypeScript hence I recommend to simplify the documentation. Again, this is constructive with the goal to reduce the number of questions and increase the number of definition files created by reducing the friction to write them.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 6, 2018

In the definition file mentioning that quote is necessary and giving the reason.

the real issue here is module foo has a well-defined meaning in the language, and it is not the one you are looking for. so we can not just make it an error. there is some historical context there, and in hindsight we should not have overloaded the meaning of the keyword module but do not think there is much we can do about this.

In the consumption, instead of telling to add a .d.ts or node_nodule to say something about that TypeScript found a .d.ts (with path) however where is an issue with X because of Y.

can you elaborate

@RyanCavanaugh
Copy link
Member

@mhegazy during failed module resolution reporting when the module name is nonrelative, we could check the global scope for a symbol with that name. If it exists we can issue a much better error - though it's probably a coinflip whether someone is just trying to import something that isn't importable, or wrote the wrong kind of module declaration.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Apr 6, 2018

In fact we can check its declaration to see if it's written as declare module foo.

Cannot find module "foo"
  An object in the global scope named 'foo' exists and can be accessed without importing it.

or (if we see declare module)

Cannot find module "foo"
  A declaration for the *global* 'foo' object exists, but was written as "declare module foo". Did you mean to write 'declare module "foo"' (with quotes)?

@mhegazy mhegazy added Suggestion An idea for TypeScript Domain: Error Messages The issue relates to error messaging and removed Question An issue which isn't directly actionable in code labels Apr 6, 2018
@mhegazy mhegazy reopened this Apr 6, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Apr 6, 2018

looks like a good compromise..

@mhegazy mhegazy added Help Wanted You can do this Good First Issue Well scoped, documented and has the green light labels Apr 6, 2018
@mhegazy mhegazy added this to the Community milestone Apr 6, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Apr 6, 2018

PRs welcomed.

@RyanCavanaugh RyanCavanaugh modified the milestones: Community, Backlog Mar 7, 2019
@sandersn sandersn added the PursuitFellowship Help wanted from Pursuit fellowship; others please avoid until Dec 19 label Sep 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Error Messages The issue relates to error messaging Good First Issue Well scoped, documented and has the green light Help Wanted You can do this PursuitFellowship Help wanted from Pursuit fellowship; others please avoid until Dec 19 Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants