【问题标题】:JWT library error: Generic type 'ModuleWithProviders<T>' requires 1 type argument(s) in Angular 10JWT 库错误:通用类型“ModuleWithProviders<T>”需要 Angular 10 中的 1 个类型参数
【发布时间】: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,这也很有用,但没有使用上面的建议。 我从错误中了解到的奇怪事实是它似乎来自库本身,而不是来自我编写的代码。

接下来我继续:

  1. rm -rf所有的node_modules
  2. rm -rf打包的jason文件
  3. 清理缓存
  4. npm install

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

【问题讨论】:

    标签: node.js angular typescript jwt


    【解决方案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),因此在使用任何库之前不要懒惰地阅读它。

    【讨论】:

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