feat(ivy): support NgModule metadata from calls that do not return ModuleWithProviders types (#27326)
Normally functions that return `ModuleWithProvider` objects should parameterize the return type to include the type of `NgModule` that is being returned. For example `forRoot(): ModuleWithProviders<RouterModule>`. But in some cases, especially those generated by nccc, these functions to not explicitly declare `ModuleWithProviders` as their return type. Instead they return a "intersection" type, one of whose members is a type literal that declares the `NgModule` type returned. For example: `forRoot(): CustomType&{ngModule:RouterModule}`. This commit changes the `NgModuleDecoratorHandler` so that it can extract the `NgModule` type from either kind of declaration. PR Close #27326
This commit is contained in:

committed by
Matias Niemelä

parent
f2a1c66031
commit
4b70a4e905
@ -441,6 +441,39 @@ describe('ngtsc behavioral tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should unwrap a ModuleWithProviders-like function if a matching literal type is provided for it',
|
||||
() => {
|
||||
env.tsconfig();
|
||||
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} from '@angular/core';
|
||||
|
||||
export interface MyType extends ModuleWithProviders {}
|
||||
|
||||
declare class RouterModule {
|
||||
static forRoot(): (MyType)&{ngModule:RouterModule};
|
||||
}
|
||||
`);
|
||||
|
||||
env.driveMain();
|
||||
|
||||
const jsContents = env.getContents('test.js');
|
||||
expect(jsContents).toContain('imports: [[RouterModule.forRoot()]]');
|
||||
|
||||
const dtsContents = env.getContents('test.d.ts');
|
||||
expect(dtsContents).toContain(`import * as i1 from 'router';`);
|
||||
expect(dtsContents)
|
||||
.toContain(
|
||||
'i0.ɵNgModuleDefWithMeta<TestModule, never, [typeof i1.RouterModule], never>');
|
||||
});
|
||||
|
||||
it('should inject special types according to the metadata', () => {
|
||||
env.tsconfig();
|
||||
env.write(`test.ts`, `
|
||||
|
Reference in New Issue
Block a user