typescript - ייבוא של סוג קונפיגורציית ספריית אימות בלבד גורם לשגיאת הפניה


יש לי ספריית אימות שנועדה לשמור על עקביות של ענייני האימות בין אפליקציות ווב שונות, בהשראת ספריית angular-oauth2-oidc. עם זאת, אני נתקע בבעיה כאשר אני בודק את האפליקציה שלי. בשירות האימות המיושם (employee-auth.service.ts), שמרחיב את שירות האימות של הספרייה, אני מקבל את השגיאה "ReferenceError: AuthLibConfig מוגדר לא."

לבסוף גיליתי שהבעיה הייתה שהייבוא של קונפיגורציית הספרייה, לפי בקשת eslint, הוא רק מסוג type. אני מחפש תובנה לגבי למה ייבוא מסוג type בלבד אינו מספיק ולמה זה גורם לשגיאת הפניה זו.

זה לא עובד, אבל מספק את דרישות eslint

import { AUTH_CONFIG_TOKEN, type AuthLibConfig, AuthLibService } from '../auth-lib';

זה עובד, אבל מחזיר שגיאת eslint

import { AUTH_CONFIG_TOKEN, AuthLibConfig, AuthLibService } from '../auth-lib';

הנה Stackblitz והוראות לשחזור:

https://stackblitz.com/edit/stackblitz-starters-n8o79p

חכה למיכל Stackblitz להתקין את התלויות

  • Ctrl+C את היישום המוגש
  • להריץ ng test
  • התנהגות צפויה
  • אני מצפה שהמבחן יעבור ללא שגיאת הפנייה. ניתן להסיר את type מהצהרת הייבוא כדי שהמבחן יעבור.

אני משתמש ב-ng-mocks; הייתי מודאג שזה באג ב-MockBuilder שלהם, אבל הסרתי את הכל למבחן יחידה רגיל של אנגולר וזה לא עשה הבדל.

ניסיתי לספק את AuthLibConfig בבדיקה וליצור מופע של AuthLibConfig ישירות בבדיקה, אבל הוא עדיין נשאר בלתי מוגדר.

תשובה #1

אז, TS מבינה ש־AuthLibConfig משמש רק כ־type בקובץ המסוים הזה, אבל אנחנו יודעים ש־AuthLibConfig הוא יותר מאשר רק type לפי השימוש שלו בפרויקט כולו. לכן אנחנו לא יכולים לייצא אותו כ־type

אם נייבא זאת כ-type, ההתייחסויות ל-AuthLibConfig בקובץ הזה לא מעובדות בזמן הריצה של הבדיקה וזה מנותק מההגדרה המקובצת בפועל שלו, ובכך גורם לכישלון הבדיקה.

זה כמו משחק משיכה בין TS שמתמקד בקובץ אחד לעומת Angular שמתמקד בפרויקט כולו, ואף אחד מהם לא מוכן לוותר על האופן שבו הם פועלים בלי מאבק.


אפשרות 1: להרפות את הכללים של TS eslint עבור 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. אבל יתכן שתצטרך לשנות זאת בכל הקבצים, לשם עקביות/קריאות טובה יותר.