From c3f1cf9e62bd4f263c75eb44b829c08b3f8352bd Mon Sep 17 00:00:00 2001 From: crisbeto Date: Tue, 15 Oct 2019 22:29:42 +0200 Subject: [PATCH 1/2] fix(ivy): throw better error for missing generic type in ModuleWithProviders Currently if a `ModuleWithProviders` is missng its generic type, we throw a cryptic error like: ``` error TS-991010: Value at position 3 in the NgModule.imports of TodosModule is not a reference: [object Object] ``` These changes add a better error to make it easier to debug. --- .../src/ngtsc/annotations/src/ng_module.ts | 24 ++++++++++++------- .../src/ngtsc/diagnostics/src/code.ts | 8 ++++++- .../test/ngtsc/fake_core/index.ts | 3 ++- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 24 +++++++++++++++++++ 4 files changed, 49 insertions(+), 10 deletions(-) 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 ea2c2b142a5b8..4a776fc6054b4 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts @@ -89,7 +89,7 @@ export class NgModuleDecoratorHandler implements DecoratorHandler this._extractModuleFromModuleWithProvidersFn(ref.node), + ref => this._extractModuleFromModuleWithProvidersFn(ref.node, name), forwardRefResolver, ]); @@ -353,12 +353,12 @@ 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 321b44d78f4be..d5b7a51172219 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -1469,6 +1469,30 @@ 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( + `ModuleWithProviders annotation of RouterModule is missing its generic type argument in NgModule of TestModule`); + }); + it('should extract the generic type if it is provided as qualified type name', () => { env.write(`test.ts`, ` import {NgModule} from '@angular/core'; From 9e218540d4257a330ba8d8606a0add0f37e4be57 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Fri, 18 Oct 2019 19:25:07 +0200 Subject: [PATCH 2/2] fixup! fix(ivy): throw better error for missing generic type in ModuleWithProviders --- .../src/ngtsc/annotations/src/ng_module.ts | 28 ++++++++++--------- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 5 ++-- 2 files changed, 18 insertions(+), 15 deletions(-) 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 4a776fc6054b4..7a814e7bec225 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts @@ -89,7 +89,7 @@ export class NgModuleDecoratorHandler implements DecoratorHandler this._extractModuleFromModuleWithProvidersFn(ref.node, name), + ref => this._extractModuleFromModuleWithProvidersFn(ref.node), forwardRefResolver, ]); @@ -353,12 +353,12 @@ export class NgModuleDecoratorHandler implements DecoratorHandler { static ɵmod: ɵɵNgModuleDefWithMeta; } `); - const errors = env.driveDiagnostics(); expect(trim(errors[0].messageText as string)) .toContain( - `ModuleWithProviders annotation of RouterModule is missing its generic type argument in NgModule of TestModule`); + `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', () => {