我有一个身份验证库,旨在使身份验证内容在各种 Web 应用程序之间保持一致,其灵感来自 Angular-oauth2-oidc 库。然而,我在测试我的应用程序时遇到了问题。在扩展了库身份验证服务的已实现身份验证服务 (employee-auth.service.ts) 中,我收到“ReferenceError:AuthLibConfig 未定义。”
我最终发现问题在于,根据 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 容器安装 deps
我正在使用 ng-mocks;我担心这是他们的 MockBuilder 的一个错误,但我将其全部剥离以进行库存角度单元测试,并且没有产生任何影响。
我尝试在测试中提供 AuthLibConfig 并直接在测试中创建 AuthLibConfig 的实例,但它仍然未定义。
因此,TS 知道
AuthLibConfig
仅在该特定文件中用作 type
,但我们知道 AuthLibConfig
根据其在整个项目中的使用情况而不仅仅是 type
。所以我们不能将其导出为 type
如果我们将其导入为
type
,则该文件中的 AuthLibConfig
引用不会在测试运行时进行处理,并且会与其实际的捆绑定义断开连接,从而导致测试失败。
这就像专注于单个文件的 TS 和专注于整个项目的 Angular 之间的拉锯战,双方都不愿意不战而屈人之兵。
一种选择是放宽一致性类型导入的 TS 规则,但如果未来的代码处理不当,可能会导致问题。
第二个选项是使用以下
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
的需要。但您可能必须在所有文件上更改它,以获得更好的一致性/可读性。