在 NgRx 中强类型存储的目的是什么?

pcm*_*ans 4 store strong-typing angular

CoreModule 是一个急切加载的模块,包含应用程序启动时所需的状态。

import * as fromCore from './state/core.reducer';

@NgModule({
  ...
  imports: [
    StoreModule.forRoot({ core: fromCore.reducer }),
Run Code Online (Sandbox Code Playgroud)

DocumentModule 是一个延迟加载的模块。

import * as fromDocument from './state/document.reducer';

@NgModule({
  ...
  imports: [
    StoreModule.forFeature('document', fromDocument.reducer),
Run Code Online (Sandbox Code Playgroud)

DocumentComponent 注入存储。

import * as fromDocument from './state/document.reducer';

constructor(private store: Store<fromDocument.State>) { }
Run Code Online (Sandbox Code Playgroud)

fromDocument.State 扩展了“核心”状态。

import * as fromCore from '../../core/state/core.reducer';

export interface State extends fromCore.State {
    document: DocumentState;
}
Run Code Online (Sandbox Code Playgroud)

我发现这种方法随处可见,但我认为它没有任何好处。当我将其设置为 fromDocument.State 不扩展 fromCore.State 时,我仍然可以访问 DocumentComponent 中状态树的“核心”部分。

this.user$ = this.store.select(fromCore.getUser);
Run Code Online (Sandbox Code Playgroud)

通过将存储注入组件中,我始终可以访问完整的状态树,无论我如何输入存储。那么强类型存储的目的到底是什么?为什么不到处使用 Store<any> 呢?我与 store 对象交互的唯一方式是 store.select 和 store.dispatch,所以据我所知,没有打字优势?

Pac*_*ac0 6

具体点

在您提到的特定情况下,键入将有助于select以映射函数作为参数的重载,例如this.store.select(s => ....)

不过,NgRx 仍然允许您进行非类型化选择。GitHub 上的相关讨论:https ://github.com/ngrx/store/issues/60

一般来说

TypeScript 的强类型和其他奇特的东西(公平地说,所有编程语言的大多数功能)并不意味着

  • 自动验证您的程序
  • 充当某种安全功能(防止数据泄露)

相反,它们是我们可怜的人类开发人员的拐杖,可以避免犯我们通常在自己的代码中编写的愚蠢错误。

示例:就像尝试调用user.namme而不是user.name在代码中晦涩的、被遗忘的部分中调用,这将导致一连串的错误。想象一下,它只在一个奇怪的地方向用户显示一些“未定义”和“登录错误”,并且只有当他按一定顺序执行 5 个非常具体的操作时,有点难以追溯和重现。

如果您使用强类型,那么在投入生产之前,编译器会快速检测到这一点。

  • @pcmcoomans 如果我错过了你的观点,那我就不好了。这里有关于商店 github 打字的相关讨论:https://github.com/ngrx/store/issues/60。(另外,作为旁注,我通常看到的模式是将存储注入到服务中,而不是直接注入组件中)。如果你执行 `this.store.select(s =&gt; ....)`,它不是按照商店的通用类型输入的吗?(在编码时帮助您,自动完成和编译错误?) (3认同)
  • 谢谢,这正是我正在寻找的信息。我只是将选择器传递到 select 函数中。当您这样做时,如何输入商店并不重要。但是当您传入mapFn时,该类型确实提供了代码完成功能。 (2认同)