【问题标题】:Angular 10 Swagger Codegen: Generic type ModuleWithProviders<T> requires 1 type argument(s)Angular 10 Swagger Codegen:通用类型 ModuleWithProviders<T> 需要 1 个类型参数
【发布时间】:2020-11-19 19:08:25
【问题描述】:

我正在生成https://editor.swagger.io/ Codegen 代理。 它在 Angular 10 中出现以下错误。如何解决?

通用类型“ModuleWithProviders”需要 1 个类型参数。

export class ApiModule {
    public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders {
        return {
            ngModule: ApiModule,
            providers: [ { provide: Configuration, useFactory: configurationFactory } ]
        };
    }

    constructor( @Optional() @SkipSelf() parentModule: ApiModule,
                 @Optional() http: HttpClient) {
        if (parentModule) {
            throw new Error('ApiModule is already loaded. Import in your base AppModule only.');
        }
        if (!http) {
            throw new Error('You need to import the HttpClientModule in your AppModule! \n' +
            'See also https://github.com/angular/angular/issues/20575');
        }
    }
}

【问题讨论】:

    标签: angular typescript swagger swagger-codegen angular10


    【解决方案1】:

    这个错误告诉你,ModuleWithProviders 类有 1 个通用参数。所以你应该像ModuleWithProviders&lt;T&gt; 一样使用它,其中 T 是一个类型。

    编辑:

    类是这样定义的:

    interface ModuleWithProviders<T> {
      ngModule: Type<T>
      providers?: Provider[]
    }
    

    .

    export class ApiModule {
      public static forRoot(configurationFactory: () => Configuration) : ModuleWithProviders<ApiModule> {
        return {
            ngModule: ApiModule,
            providers: [ { provide: Configuration, useFactory: configurationFactory } ]
        };
    }
    

    查看资源:

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

    【讨论】:

    • 但是从正确的实践来看,我们不应该修改从 Swagger Codegen 生成的代码,还有其他方法可以解决这个问题吗?也许 swagger-codegen-cli 命令中的其他属性?
    • @Henry 我同意,您可以指定自定义模板供 swagger 使用。请参阅我的回复以了解我们在生产中使用的解决方案
    【解决方案2】:

    我们偶然发现了同样的问题。幸运的是,您可以使用 -t 开关向 swagger-codegen-cli 提供自定义 *.mustache 模板(请参阅 the swagger doc)。

    我们改编后的 api.module.mustache 看起来像这样:

    import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core';
    import { Configuration } from './configuration';
    {{#useHttpClient}}import { HttpClient } from '@angular/common/http';{{/useHttpClient}}
    {{^useHttpClient}}import { Http } from '@angular/http';{{/useHttpClient}}
    
    {{#apiInfo}}
    {{#apis}}
    import { {{classname}} } from './{{importPath}}';
    {{/apis}}
    {{/apiInfo}}
    
    @NgModule({
      imports:      [],
      declarations: [],
      exports:      [],
      providers: [
        {{#apiInfo}}{{#apis}}{{classname}}{{#hasMore}},
        {{/hasMore}}{{/apis}}{{/apiInfo}} ]
    })
    export class ApiModule {
        public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders<ApiModule> {
            return {
                ngModule: ApiModule,
                providers: [ { provide: Configuration, useFactory: configurationFactory } ]
            };
        }
    
        constructor( @Optional() @SkipSelf() parentModule: ApiModule,
                     @Optional() http: {{#useHttpClient}}HttpClient{{/useHttpClient}}{{^useHttpClient}}Http{{/useHttpClient}}) {
            if (parentModule) {
                throw new Error('ApiModule is already loaded. Import in your base AppModule only.');
            }
            if (!http) {
                throw new Error('You need to import the {{#useHttpClient}}HttpClientModule{{/useHttpClient}}{{^useHttpClient}}HttpModule{{/useHttpClient}} in your AppModule! \n' +
                'See also https://github.com/angular/angular/issues/20575');
            }
        }
    }
    

    唯一需要的更改是将ModuleWithProviders 替换为ModuleWithProviders&lt;ApiModule&gt;。 之后生成的 api.module.ts 将适用于 Angular 10。

    【讨论】:

    • 不确定这是如何工作的,但会试一试,谢谢!
    • @Henry 我们的电话如下所示:java -jar swaggercodegen.jar generate -l typescript-angular -i api-spec.yaml -o "${Temp}\src" --additional-properties ngVersion=10 -t "\Path\to\Templates\"。最后一个参数将 Swagger 指向我们的自定义模板。该目录包含一个子目录“angular”,其中包含我们修改后的模块模板文件:angular/api.module.mustache。确保目录和文件名正确。否则 Swagger 将忽略它们。这没有很好的记录。我不得不查阅 Swagger 源代码才能弄清楚。
    • 您究竟是如何创建“api.module.mustache”文件的?我尝试创建它,但它最终成为“.txt”文件扩展名
    • @Henry 尝试重命名包含扩展名的文件。也就是说,现在大多数文本编辑器都允许您保存具有任何给定扩展名的文件。
    • 我尝试使用 notepad++ 但无济于事 =/ 有没有推荐的文本编辑器?
    【解决方案3】:

    io.swagger.swagger-codegen 自版本 2.4.17 起完全支持 Angular 10。您可以详细了解此pull request 中提供的修复程序。

    正如djf 提到的,在调用generate 时使用参数--additional-properties ngVersion=10 来告诉io.swagger.swagger-codegen 使用Angular 10。

    【讨论】:

    猜你喜欢
    • 2021-04-19
    • 2020-12-06
    • 2020-11-14
    • 2020-10-26
    • 2017-01-09
    • 2023-03-14
    • 2017-06-05
    • 2017-10-23
    • 1970-01-01
    相关资源
    最近更新 更多