JWT 库错误:通用类型“ModuleWithProviders<T>”需要 Angular 10 中的 1 个类型参数

Posted

技术标签:

【中文标题】JWT 库错误:通用类型“ModuleWithProviders<T>”需要 Angular 10 中的 1 个类型参数【英文标题】:JWT library error: Generic type 'ModuleWithProviders<T>' requires 1 type argument(s) in Angular 10 【发布时间】:2021-04-19 16:25:40 【问题描述】:

对于我正在使用的身份验证项目:

Angular CLI: 11.0.4 用于前端

Node: 10.19.0 用于后端

OS: linux x64

我在ng serve 之后收到以下错误,我不确定为什么会这样,错误似乎在库中 node_modules/angular2-jwt/angular2-jwt.d.ts而不是我写的代码:

node_modules/angular2-jwt/angular2-jwt.d.ts:88:41 - 错误 TS2314: 通用类型“ModuleWithProviders”需要 1 个类型参数。

static forRoot(config: AuthConfig): ModuleWithProviders;

也与此相关(所以我相信错误是并发的,甚至,恐怕是可互换的),因为它会在显示 'ModuleWithProviders&lt;T&gt;' 错误时立即显示,所以我认为显示它们是有意义的两者都链接在一起:

错误:node_modules/angular2-jwt/angular2-jwt.d.ts:1:77 - 错误 TS2307:找不到模块“@angular/http”或其对应类型 声明。

1 导入 Http, Request, RequestOptions, RequestOptionsArgs, Response 来自“@angular/http”;

所以我遇到的困难也是由于我不确定代码的哪些部分受到影响,所以为了完整起见,我将把app.module.ts和带有jwt include的文件放在一起

app.module.ts

import  ValidateService  from './services/validate.service';
import  FlashMessagesModule  from 'angular2-flash-messages'; 
import  HttpClientModule  from '@angular/common/http';
import  AuthService  from './services/auth.service'; 
import  AuthGuard  from './guards/auth.guards';


const appRoutes: Routes = [
  path:'', component: HomeComponent,
  path:'register', component: RegisterComponent,
  path:'login', component: LoginComponent,
  path:'dashboard', component: DashboardComponent, canActivate: [AuthGuard],
  path:'profile', component: ProfileComponent, canActivate: [AuthGuard],
]

@NgModule(
  declarations: [
    AppComponent,
    NavbarComponent,
    LoginComponent,
    RegisterComponent,
    HomeComponent,
    DashboardComponent,
    ProfileComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    RouterModule.forRoot(appRoutes),
    FlashMessagesModule.forRoot(),
    HttpClientModule,
  ],
  providers: [ValidateService, AuthService, AuthGuard],
  bootstrap: [AppComponent]
)
export class AppModule  

auth.service.ts

import  Injectable  from '@angular/core';
import  HttpClient, HttpHeaders  from '@angular/common/http';
import  map  from 'rxjs/operators';
import  tokenNotExpired  from 'angular2-jwt';


@Injectable(
  providedIn: 'root'
)
export class AuthService 
  authToken: any;
  user: any;

  constructor(private httpClient: HttpClient)  

  registerUser(user) 
    const httpOptions = 
      headers: new HttpHeaders(
        'Content-Type':  'application/json',
      )
    ;
    return this.httpClient.post('http://localhost:3000/users/register', user, httpOptions);
  

  authenticateUser(user) 
    const httpOptions = 
      headers: new HttpHeaders(
        'Content-Type':  'application/json',
      )
    ;
    return this.httpClient.post('http://localhost:3000/users/authenticate', user, httpOptions);
  

  getProfile() 
    const httpOptions = 
      headers: new HttpHeaders(
        'Content-Type':  'application/json',
        Authorization: this.authToken,
      )
    ;
    this.loadToken();
    return this.httpClient.get('http://localhost:3000/users/profile', httpOptions);
  

  storeUserData(token, user) 
    localStorage.setItem('id_token', token);
    localStorage.setItem('user', JSON.stringify(user));
    this.authToken = token;
    this.user = user;
  

  loadToken() 
    const token = localStorage.getItem('id_token');
    this.authToken = token;
  

  loggedIn() 
    return tokenNotExpired();
  

  logout() 
    this.authToken = null;
    this.user = null;
    localStorage.clear();
  

profile.components.ts

import  Component, OnInit  from '@angular/core';
import  AuthService  from '../../services/auth.service';
import  Router  from '@angular/router';  

@Component(
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
)
export class ProfileComponent implements OnInit 
  user: Object = ;

  constructor(private authService: AuthService, private router: Router)  

  ngOnInit(): void 
    this.authService.getProfile().subscribe(profile => 
      this.user = profile;
    ,
    err => 
      console.log(err);
      return false;
    )
  

我对如何解决问题进行了研究,到目前为止我能够找到以下内容: this post 非常有用,因为它有我同样的问题。 答案需要bug report repo,但是,它没有提供任何答案。 提供的答案建议插入以下代码:

declare module "@angular/core" 
  interface ModuleWithProviders<T = any> 
    ngModule: Type<T>;
    providers?: Provider[];
  

很遗憾,这不是一个可接受的答案,我不确定我可以将这段代码放在我上面提供的 app.module.ts 的任何部分的什么位置。

我还研究了this post,这也很有用,但没有使用上面的建议。 我从错误中了解到的奇怪事实是它似乎来自库本身,而不是来自我编写的代码。

接下来我继续:

    rm -rf所有的node_modules rm -rf打包的jason文件 清理缓存 npm install

但是结果是一样的,我总是在同一个库上收到同样的错误。 如果有人遇到同样的问题,请您分享一下它是如何解决的,我应该做些什么来解决这个问题。

【问题讨论】:

【参考方案1】:

将这段代码插入到 angular2-jwt.d.ts 类中并确认类更改:

declare module "@angular/core" 
      interface ModuleWithProviders<T = any> 
        ngModule: Type<T>;
        providers?: Provider[];
      
    

但是你应该使用比这个更新的库,比如@auth0/angular-jwt 安装此库后,您必须在 app.module.ts 类中注册其模块:

  import JwtModule from '@auth0/angular-jwt'


  imports: [
     JwtModule.forRoot(
        config: 
          tokenGetter:() => 
             return localStorage.getItem('access_token'); 
          ,
        ,
     )
  ],

然后你可以在你的 AuthService 类中使用它:

 import JwtHelperService from '@auth0/angular-jwt';

 constructor(public jwtHelper: JwtHelperService) 
   

 isAuthenticated(): boolean 
    return !this.jwtHelper.isTokenExpired(this.token);
  

所有这些都在带有示例的简短文档中进行了解释 (https://www.npmjs.com/package/@auth0/angular-jwt),因此在使用任何库之前不要懒惰地阅读它。

【讨论】:

以上是关于JWT 库错误:通用类型“ModuleWithProviders<T>”需要 Angular 10 中的 1 个类型参数的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的通用服务出现“无法实例化实现类型”错误?

使用 php-jwt 库解码 firebase 自定义令牌时出现 openssl_verify() 错误

Spring Boot > 2.2.7 的令牌类型为“at+jwt”时 JWT 错误的解码

JWT解码时字符串声明类型错误?

JWT decode() 必须是数组错误类型

Firebase JWT 库无法验证 Python JWT 令牌