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

Module not found when using type from .d.ts file #4874

Closed
Buslowicz opened this issue Feb 21, 2017 · 40 comments
Closed

Module not found when using type from .d.ts file #4874

Buslowicz opened this issue Feb 21, 2017 · 40 comments

Comments

@Buslowicz
Copy link

Buslowicz commented Feb 21, 2017

I started this issue on angular/angular issues, but seems to be related to CLI, so just copy-pasting the issue here :).

I'm submitting a ...

[x] bug report

Current behavior
When assigning a custom type (like Post, or User) to a decorated property (with either ng decorator like @Input() or a custom one), where type is declared in d.ts file, angular throws an error:

ERROR in ./src/app/app.component.ts
Module not found: Error: Can't resolve './types' in '/home/dracco/projects/ng2/src/app'
 @ ./src/app/app.component.ts 11:0-31
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://localhost:4200/ ./src/main.ts
webpack: Failed to compile.

This does not happen if:

  • type is added through generic (like Array<Post>) OR
  • no decorator is added to property OR
  • file with declaration has .ts extension instead of .d.ts

Expected behavior
No error should be thrown. property should have given type.

Minimal reproduction of the problem with instructions

  1. Run ng init to create a new Angular project.
  2. Create a d.ts file in app folder
  3. Add an exported interface to the .d.ts file
  4. Import above interface in component file
  5. Add a property with decorator and above type (e.g. @Input() prop: MyType)
  6. Run ng serve

What is the motivation / use case for changing the behavior?
The default workflow in TypeScript suggests keeping declarations and interfaces in .d.ts file. Simple Angular components might not use Observables and still accept data from the host. I am actually surprised nobody mentioned and solved it so far as it is pretty severe (it also happens in 4.0.0-beta.8).

Please tell us about your environment:

  • OS: linux x64 (Ubuntu 16.10)
  • Angular version: 2.3.1, 2.2.4, 4.0.0-beta.8
  • Angular CLI version: 1.0.0-beta.28.3
  • Node (for AoT issues): 7.5.0
  • NPM: 4.1.2
@nikoTM
Copy link

nikoTM commented Feb 21, 2017

Possibly has to do with this issue.

@Buslowicz
Copy link
Author

Maybe, though I do refer to d.ts file without extension in the import statement.

@aaron-bond
Copy link

Why not import the .d.ts into the typings.d.ts file instead of into the component?

@Buslowicz
Copy link
Author

Because it's generated and exports interfaces and namespaces, not declares them globally.

@filipesilva
Copy link
Contributor

This isn't a CLI issue, but rather a TypeScript/Angular issue.

@Buslowicz
Copy link
Author

They said it's cli issue. Is Angular and CLI 2 separate products? If not, do cooperate. This issue does not happen if using webpack starter, so I don't believe it's issue on Angular or TypeScript side itself. Please reopen this issue and investigate it if you want people to believe that Angular is a serious platform.

@basst314
Copy link

basst314 commented Mar 17, 2017

I can confirm this issue, @Draccoz @filipesilva .

It does not happen when you change the filename from .d.ts to .ts.
It also does not happen when you change your import from import { Something } from 'yourlib'; to import { Something } from 'yourlib.d';

I just moved a working project from a webpack-starter seed (TypeScript/Angular) to CLI and got this error, so I assume it has something to do with the generated CLI project.

I'm using @angular/cli: 1.0.0-rc.2

@Buslowicz
Copy link
Author

Thanks @basst314. I'm afraid though that @filipesilva doesn't care about it at all.

@basst314
Copy link

Hi @filipesilva ,
how are we supposed to handle custom typing files like my-types.d.ts in projects running on angular-cli when we want to use them in our component inputs as @Input() element: MyType ?

As written above, regular typescript imports like import { MyType } from 'my-types' don't really work when running on a cli-project.

Do we have to register our typing-files somewhere in the cli-config to be found during the build?
Or is there a documentation or guide you can refer us to?

Any help is very much appreciated!
Thanks!

@filipesilva
Copy link
Contributor

This might actually be #2034.

@basst314
Copy link

Hey @Draccoz, can you confirm that this does only happen when doing a normal jit build with ng build, but does work like a charm when building aot with ng build -aot? This is what I'm experiencing.

@filipesilva, #2034 might be related, but this one breaks the build, the other displays a warning and does not break the build. Also the concrete error message is different.
Could you please consider reopening this issue and take a look at @Draccoz github repo to reproduce the error?

Thanks!

@Buslowicz
Copy link
Author

Confirming the above. ng build -aot works correctly, while ng build produces:

ERROR in ./src/app/app.component.ts
Module not found: Error: Can't resolve './types' in '/home/dracco/projects/ng2-type-import-issue/src/app'
@ ./src/app/app.component.ts 11:0-31
@ ./src/app/app.module.ts
@ ./src/main.ts
@ multi ./src/main.ts

@18steps
Copy link

18steps commented May 8, 2017

Can confirm this is still an issue in Angular CLI 1.0.2

@angular/cli: 1.0.2
node: 7.10.0
os: win32 x64
@angular/animations: 4.1.1
@angular/common: 4.1.1
@angular/compiler: 4.1.1
@angular/core: 4.1.1
@angular/forms: 4.1.1
@angular/http: 4.1.1
@angular/material: 2.0.0-beta.3
@angular/platform-browser: 4.1.1
@angular/platform-browser-dynamic: 4.1.1
@angular/router: 4.1.1
@angular/cli: 1.0.2
@angular/compiler-cli: 4.1.1

@filipesilva
Copy link
Contributor

@basst314 you're right, #2034 is a warning and this is an error. Reopening.

@filipesilva filipesilva added P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful effort2: medium (days) freq1: low Only reported by a handful of users who observe it rarely package4: @angular-sdk/webpack severity3: broken labels May 9, 2017
@filipesilva filipesilva reopened this May 9, 2017
@artparks
Copy link

artparks commented Jun 2, 2017

any news on this? it's pretty annoying!

@cipchk
Copy link
Contributor

cipchk commented Jun 11, 2017

+1

@alexey-kozlenkov
Copy link

alexey-kozlenkov commented Jul 10, 2017

+1 Any updates on this?

@marshall007
Copy link

marshall007 commented Jul 20, 2017

Does anyone have a workaround for this (aside from using the any type on the input)?

[edit]: a workaround for anyone following along is to declare the property with an intersection type:

export class FooComponent {
  @Input() public foo: IFoo; // does not work
  @Input() public foo: IFoo & { }; // works
}

@18steps
Copy link

18steps commented Jul 21, 2017 via email

@bmxmaga
Copy link

bmxmaga commented Jul 25, 2017

@18steps I'm affraid this is not possible in my case.

TypeScript treats *.d.ts files in a special way that it doesn't compile them into the bundle.

In my project (non-angular), I use *.d.ts file which is placed outside the root of my project. The reason for that is because the file is shared with another project (angular + angular/cli). When compiling, TypeScript refers to that file with '../../file_path.d.ts' but keeps the reference to the root path properly. Once I change the file name to *.def.ts it is no longer special for TS and the compiler moves the root path two levels up. This ruins the whole tree of compiled files.

Here's an example how it looks when I use *.d.ts file:

└ my-project/  <-- I run tsc from this location
  └ tsconfig.json
  └ src/
    └ app.ts  <-- (imports something from ../../d/definitions.d.ts)
  └ dist/  <-- this is generated by tsc
    └ app.js
└ d/
  └ definitions.d.ts

And here's how it looks when I change the *.d.ts to *.def.ts (or anything else):

└ my-project/  <-- tsc is run from this place
  └ tsconfig.json
  └ src/
    └ app.ts  <-- (imports something from ../../d/definitions.def.ts)
  └ dist/  <-- this is generated by tsc
    └ my-project  <-- this is wrong
      └ src
        └ app.js
      └ d
        └ definitions.def.ts
└ d/
  └ definitions.def.ts

If you take a look at the /dist folder in the second example you'll notice that the compiler "moved" the root of the application 2 levels up.

I was searching for a solution for this behavior in the TS documentation but didn't find anything useful. Maybe someone knows some trick in the tsconfig.json that would solve my problem but this is something different from the bug described in this thread.

@basst314
Copy link

basst314 commented Aug 8, 2017

@filipesilva and @hansl can you estimate when there will be time to fix this issue? I see it has been labeled 'priotity urgent' but so far nothing has happened.

@PhotoPaul
Copy link

Another workaround similar to marshall007's is to declare it like this:

export class FooComponent {
@Input() public foo: IFoo; // does not work
@Input() public foo: IFoo | any; // works
}

@FrancescoBorzi
Copy link

I can also confirm what @PhotoPaul said.

This is a serious issue, I hope it can be solved as soon as possible.

@vmorris
Copy link

vmorris commented Nov 17, 2017

@hansl let's get some kind of resolution please?

@curtstate
Copy link

curtstate commented Jan 29, 2018

In my case it seems to be failing when it is loading the typescript via webpack (see ng eject -ed webpack config):

      {
        "test": /\.ts$/,
        "loader": "@ngtools/webpack"
      }

I get this myself when I use webpack (the 'Fingerprint2' class name corresponds to a .d.ts file I have under node_modules and typescript's compiler finds it fine):

error TS2304: Cannot find name 'Fingerprint2'.
error TS2304: Cannot find name 'Fingerprint2'.
error TS7006: Parameter 'result' implicitly has an 'any' type.
error TS7006: Parameter 'components' implicitly has an 'any' type.

it seems like it isn't finding the .d.ts file in the @ngtools/webpack loader when running webpack.

@hansl hansl removed their assignment Feb 6, 2018
@filipesilva filipesilva added area: @ngtools/webpack and removed effort2: medium (days) freq1: low Only reported by a handful of users who observe it rarely P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful severity3: broken labels Feb 14, 2018
@Pumpuli
Copy link

Pumpuli commented Aug 9, 2018

In my project I'm getting the same error message as Asken. It only happens when using AOT. And I also narrowed it down to using a type imported from a package (with .d.ts) inside a decorator (e.g. @NgModule). If I use the imported type outside of a decorator, the build succeeds. In fact, I'm probably going to use InjectionTokens as a workaround, because then I won't have to use the imported types inside decorators; and using them for injection in component constructor seems to be fine. Also if I just define the interface in the same file (not .d.ts), then it works fine inside a decorator. I tried this in both Angular 5 and 6.

The error message itself seems to originate from inside enhanced-resolver. The file it can't resolve is inside the package only as a .d.ts file.

ERROR in ./src/app/app.module.ngfactory.js
Module not found: Error: Can't resolve 'my-interface-package/lib/IMyService' in '<project folder>\src\app'
My setup:
import { IMyService } from 'my-interface-package';
import { MyActualService } from 'my-implementation-package';

// IMyService is actually not an interface, but an abstract class, so it can be used for DI.

@NgModule({
    providers: [
        { provide: IMyService, useClass: MyActualService }
    ]
})
export class AppModule {}

Planned workaround for now:

export const MY_SERVICE_TOKEN = new InjectionToken('IMyService');
@NgModule({
    providers: [
        { provide: MY_SERVICE_TOKEN, useClass: MyActualService }
    ]
})
export class AppModule {}

@Component({
    template: '...',
})
export class SomeComponent {
    // Using IMyService here for parameter type does not cause an error.
    constructor(@Inject(MY_SERVICE_TOKEN) private myService: IMyService) {}
}

@Jerome2606
Copy link

I'm still have this issue as well. In AOT only

@dudewad
Copy link

dudewad commented Aug 28, 2018

I started getting this today, where yesterday I didn't have it. The only thing I can think of is that between now and then, I upgraded to the following:

    "@angular-devkit/build-angular": "~0.8.0-rc.0",
    "@angular-devkit/build-ng-packagr": "~0.8.0-rc.0",
    "ng-packagr": "^4.1.0",

from:

    "@angular-devkit/build-angular": "~0.6.8",
    "@angular-devkit/build-ng-packagr": "~0.6.8",
    "ng-packagr": "^3.0.0-rc.2",

I am going to revert, rebuild, and report back.

@dudewad
Copy link

dudewad commented Aug 28, 2018

Reverting did not help. I'm still going to keep poking around.
FWIW, I'm building libraries (separate projects created by ng generate library) that compile to dist in my root directory. I for some reason feel like they WERE exporting index.ts files and are now only building to index.d.ts files, but I could definitely be wrong about that. All I know is, index.d.ts files, as far as I know, are not compiled into the project bundles. Am I correct in thinking that?

@dudewad
Copy link

dudewad commented Aug 28, 2018

I'm not sure if I'm even experiencing the same issue. However, I pointed my tsconfig aliases for my library projects from their dist/projectname directories (the built projects) to the source projects (libs/projectname/src) and it compiled fine.
I'm concerned that that will de-optimize my build, though... is that something I should worry about, or is this okay to do?

@alexeagle alexeagle added the needs: discussion On the agenda for team meeting to determine next steps label Sep 10, 2018
@ngbot ngbot bot added this to the needsTriage milestone Sep 10, 2018
@hansl
Copy link
Contributor

hansl commented Sep 13, 2018

@dudewad Can you please provide a reproduction repository we can use to investigate this? It seems there are some metadata emitted from Angular's decorators, and we should be stripping those before we compile in AOT.

@hansl
Copy link
Contributor

hansl commented Sep 13, 2018

@dudewad This seems like a different issue. If you could provide a reproduction and create a new issue (here), that'd be great. Thanks!

I'm closing this issue as fixed.

@hansl hansl closed this as completed Sep 13, 2018
@hansl hansl removed the needs: discussion On the agenda for team meeting to determine next steps label Sep 13, 2018
@FrancescoBorzi
Copy link

This bug is still happening with version 7.1.4 and it's quite annoying.

Also (hoping that this can help with the bug resolution), I noticed that if you create two files like:

  • myfile.t
  • myfile.d.ts

and try to include in myfile.ts something exported by myfile.d.ts, the compiler will say that there is a circular dependency -> so it doesn't distinguish between those two files.

@LokeshBadgujar
Copy link

Yes, This bug is still happening with version 7.1.4.

@cbossi
Copy link

cbossi commented Mar 21, 2019

I had the same problem: Files with the ending .d.ts could not be resolved.

In my case the problem caused by the option annotateForClosureCompiler of the angularCompilerOptions: https://angular.io/guide/aot-compiler#annotateforclosurecompiler

Setting annotateForClosureCompiler to false (or removing it, since false is the default value) in tsconfig.json fixed the problem:

"angularCompilerOptions": {
    "annotateForClosureCompiler": false
}

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests