0

I'm maintaining an Angular library, which is generated by Angular Cli. Inside the workspace there is a library and a demo-app, which is a standard architecture for all of Angular libray created from angular-cli.

Currently I'm upgrading my library to new release of Angular 9.

I use the automatic upgrade soultion with ng update. After fixing some migration issues(some API are deprecated). The library can be build successfully.

But I am blocked by the build of the demo-app which has the library as dependency. I got ngcc error. After some research online I know the background: https://angular.io/guide/ivy#maintaining-library-compatibility; Library build fails with Angular 9

Even though I understand what's ngcc and why we need it for now, I can't still fix the build error.

In my library I have too modules as following:

// the first module

@NgModule({
   ...
})
export class FirstModule {
  public static forRoot(
    FirstConfig: Config
  ): ModuleWithProviders<FirstModule> {
    return DIYModuleWithProviders(FirstModule, FirstConfig);
  }
  ...
 }

// the second module

@NgModule({
   ...
})
export class SecondModule {
  public static forRoot(
    SecondConfig: Config
  ): ModuleWithProviders<SecondModule> {
    return DIYModuleWithProviders(SecondModule, SecondConfig);
  }
  ...
 }

These two modules both call a function imported from other module in the fotRoot method as following:

export function DIYModuleWithProviders(
  module: any,
  config: Config
): ModuleWithProviders {
  return {
    ngModule: module,
    providers: [
      {
        ...
      },
      {
        ...
      }
    ]
  };
}

This function just return a ModuleWithProviders for the forRoot method. I abstract the function here, because these two module has the same logic for this part.

As I mentioned, the library iteself is build successfully (based on the google Angular team's documents, Library is still using old View Eigine instead of Ivy compiler). But the demo-app failed to build with following error:

Compiling my-library : module as esm5
Error: Error on worker #1: Error: No typings declaration can be found for the referenced NgModule class in function DIYModuleWithProviders(module, config) {
    return {
        ngModule: module,
        providers: [
            {
                ...
            },
            {
                ...
            }
        ]
    };
}.

based on the google Angular team's document: demo-app use Ivy compiler, that's the reason why ngcc comes here.

I tuned the type of DIYModuleWithProviders for a while but can't work it out. Based on the link https://angular.io/guide/migration-module-with-providers, in Angualr 9, ModuleWithProviders must have generic type. So change it to ModuleWithProviders<any>, but it doesn't work.

https://github.com/500tech/angular-tree-component/issues/721. Is there any ideas?

1 Answer 1

1

You have to give your ModuleWithProviders a type reference.

ModuleWithProviders<YourType>

See there: https://angular.io/guide/migration-module-with-providers

Edit: To be more precice, your DIYModuleWithProviders function also have to return a typed module.

Edit: Try it like that:

export function DIYModuleWithProviders<T>(
  module: T,
  config: Config
): ModuleWithProviders<T> {
  return {
    ngModule: module,
    providers: [
      {
        ...
      },
      {
        ...
      }
    ]
  };
}

or just remove the function and hook it into your Module like that:

export class YourModule {

  public static withOptions(options: YourModuleOptions ): ModuleWithProviders<YourModule> {
    return {
      ngModule: YourModule ,
      providers: [...]
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I tried to change to ModuleWithProviders<any>. still doesn't work. Same issue.
I've updated my post, maybe one of the two ways would work for your. We use the second one for our internal libraries
Thank you. I used the second method, it works. But it generated duplicated code. The method with generic is my desired method. But came some tricky TS type issues.

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.