typescript - การนำเข้าเฉพาะชนิดการกำหนดค่าของห้องสมุดการตรวจสอบสิทธิ์ทำให้เกิดข้อผิดพลาดอ้างอิง
ฉันมีไลบรารีการยืนยันตัวตนที่ออกแบบมาเพื่อให้การยืนยันตัวตนสอดคล้องกันในเว็บแอปต่างๆ ได้ ได้รับแรงบันดาลใจจากไลบรารี angular-oauth2-oidc อย่างไรก็ตามฉันเจอปัญหาเมื่อทดสอบแอปของฉัน ในบริการการยืนยันตัวตนที่นำไปใช้งาน (employee-auth.service.ts) ซึ่งขยายจากบริการการยืนยันตัวตนของไลบรารี ฉันได้รับข้อผิดพลาด "ReferenceError: AuthLibConfig is not defined."
ฉันค้นพบในที่สุดว่าปัญหาคือการนำเข้าของไลบรารี config ตามคำสั่งของ eslint เป็นเพียงประเภทเท่านั้น ฉันกำลังมองหาคำอธิบายเกี่ยวกับสาเหตุที่การนำเข้าแบบประเภทเพียงอย่างเดียวไม่เพียงพอและทำไมมันถึงทำให้เกิดข้อผิดพลาดการอ้างอิงนี้
นี่ใช้ไม่ได้ แต่ผ่าน eslint
import { AUTH_CONFIG_TOKEN, type AuthLibConfig, AuthLibService } from '../auth-lib';
นี่ใช้ได้ แต่ทำให้เกิดข้อผิดพลาด eslint
import { AUTH_CONFIG_TOKEN, AuthLibConfig, AuthLibService } from '../auth-lib';
นี่คือสแตกบลิทซ์และคำแนะนำในการทำซ้ำ:
https://stackblitz.com/edit/stackblitz-starters-n8o79p
รอให้คอนเทนเนอร์ Stackblitz ติดตั้ง dependencies
- กด Ctrl+C ที่แอปพลิเคชันที่ให้บริการอยู่
- รัน ng test
- พฤติกรรมที่คาดหวัง
- ฉันคาดว่าการทดสอบจะผ่านโดยไม่มีข้อผิดพลาดการอ้างอิง สามารถลบ type ออกจากคำสั่งนำเข้าเพื่อให้การทดสอบผ่านได้
ฉันกำลังใช้ ng-mocks; ฉันกังวลเกี่ยวกับการที่มันอาจเป็นบั๊กของ MockBuilder ของพวกเขา แต่ฉันตัดทุกอย่างออกสำหรับการทดสอบหน่วย Angular ปกติและมันก็ไม่ได้ทำให้เกิดความแตกต่างใด ๆ
ฉันได้ลองให้ AuthLibConfig ในการทดสอบและสร้างอินสแตนซ์ของ AuthLibConfig โดยตรงในทดสอบแล้ว แต่ก็ยังคงเป็น undefined อยู่ดี
คำตอบ #1
ดังนั้น TS เข้าใจว่า AuthLibConfig ถูกใช้เป็นเพียง type ในไฟล์นั้นเท่านั้น แต่เราทราบว่า AuthLibConfig มากกว่าเพียง type ตามที่ใช้งานในโปรเจกต์ทั้งหมด ดังนั้นเราจึงไม่สามารถส่งออกมันเป็น type ได้
ถ้าเรา import มันเป็น type การอ้างอิง AuthLibConfig ในไฟล์นั้นจะไม่ถูกประมวลผลในระหว่างรันไทม์ของการทดสอบ และมันจะถูกตัดออกจากการกำหนดค่าที่บรรจุมาจริง ซึ่งส่งผลให้การทดสอบล้มเหลว
มันเหมือนกับการชักเย่อระหว่าง TS ที่มุ่งเน้นไปที่ไฟล์เดียวกับ Angular ที่มุ่งเน้นไปที่ทั้งโปรเจกต์ และไม่มีฝ่ายใดยอมแพ้วิธีการทำงานของตนโดยไม่ต่อสู้
ตัวเลือก 1: ผ่อนปรนกฎ eslint ของ TS สำหรับ consistent-type-imports แต่สามารถทำให้เกิดปัญหาได้หากโค้ดในอนาคตไม่ได้รับการจัดการอย่างถูกต้อง
(หรือ)
ตัวเลือกที่ 2: เขียนบริการที่ถูกฉีดใหม่โดยใช้วิธี inject ตามด้านล่าง,
จาก
...
export class EmployeeAuthService extends AuthLibService<Employee> {
public constructor(
@Inject(HttpClient) private readonly http: HttpClient,
@Inject(OAuthService) oauth: OAuthService,
@Inject(AUTH_CONFIG_TOKEN) config: AuthLibConfig
) {
super(oauth, config);
}
...
}
ถึง
import { inject } from '@angular/core'
...
export class EmployeeAuthService extends AuthLibService<Employee> {
private readonly http = inject(HttpClient)
oauth = inject(OAuthService)
config = inject(AUTH_CONFIG_TOKEN)
...
}
สิ่งนี้จะทำให้ไม่จำเป็นต้องใช้ AuthLibConfig เป็น type แต่คุณอาจต้องเปลี่ยนในทุกไฟล์เพื่อความสอดคล้อง/อ่านง่ายที่ดียิ่งขึ้น
