diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts index ea2c2b142a..7a814e7bec 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts @@ -358,7 +358,7 @@ export class NgModuleDecoratorHandler implements DecoratorHandler = any; +// T defaults to `any` to reflect what is currently in core. +export type ModuleWithProviders = any; export class ChangeDetectorRef {} export class ElementRef {} diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 321b44d78f..7e349632d7 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -1469,6 +1469,31 @@ runInEachFileSystem(os => { 'i0.ɵɵNgModuleDefWithMeta'); }); + it('should throw if ModuleWithProviders is missing its generic type argument', () => { + env.write(`test.ts`, ` + import {NgModule} from '@angular/core'; + import {RouterModule} from 'router'; + + @NgModule({imports: [RouterModule.forRoot()]}) + export class TestModule {} + `); + + env.write('node_modules/router/index.d.ts', ` + import {ModuleWithProviders, ɵɵNgModuleDefWithMeta} from '@angular/core'; + + declare class RouterModule { + static forRoot(): ModuleWithProviders; + static ɵmod: ɵɵNgModuleDefWithMeta; + } + `); + const errors = env.driveDiagnostics(); + expect(trim(errors[0].messageText as string)) + .toContain( + `RouterModule.forRoot returns a ModuleWithProviders type without a generic type argument. ` + + `Please add a generic type argument to the ModuleWithProviders type. If this ` + + `occurrence is in library code you don't control, please contact the library authors.`); + }); + it('should extract the generic type if it is provided as qualified type name', () => { env.write(`test.ts`, ` import {NgModule} from '@angular/core';