You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NgRx的store.select调用selectAllBookings时出现类型错误

解决NgRx中store.select(selectAllBookings)的类型错误

执行代码public allBookings = this.store.select(selectAllBookings);时出现如下类型错误:

Overload 1 of 9, '(mapFn: (state: object) => Booking[]): Observable<Booking[]>', gave the following error.
  Argument of type 'MemoizedSelector<AppState, Booking[], (s1: BookingState) => Booking[]>' is not assignable to parameter of type '(state: object) => Booking[]'.
    Types of parameters 'state' and 'state' are incompatible.
      Property 'bookings' is missing in type '{}' but required in type 'AppState'.
Overload 2 of 9, '(key: never): Observable<never>', gave the following error.
  Argument of type 'MemoizedSelector<AppState, Booking[], (s1: BookingState) => Booking[]>' is not assignable to parameter of type 'never'. [plugin angular-compiler]

src/app/booking-table/booking-table.component.ts:14:41:
 14 │   public allBookings = this.store.select(selectAllBookings);
    ╵                                          ~~~~~~~~~~~~~~~~~

'bookings' is declared here.

src/app/store/app.state.ts:4:4:
 4 │     bookings: BookingState;

相关代码文件

AppState.ts

import { BookingState } from "./booking.reducer";

export interface AppState {
    bookings: BookingState;
}

booking.action.ts

import { createAction, props } from "@ngrx/store";
import { Booking } from "../model/booking.model";

export const loadBookings = createAction(
    '[Booking API] Load bookings'
);

export const loadBookingsSuccess = createAction(
    '[Booking API] Booking Load Success',
    props<{ bookings: Booking[] }>()
);

booking.effects.ts

import { Injectable } from "@angular/core";
import { createEffect, ofType, Actions } from "@ngrx/effects";
import { map, switchMap, from } from "rxjs";
import { BookingService } from "../booking.service";
import * as BookingActions from "../store/booking.actions";
import { Store } from "@ngrx/store";
import { AppState } from "./app.state";

@Injectable()
export class BookingEffects {

    constructor(private actions$: Actions, private bookingService: BookingService, private store: Store<AppState>) {}

    loadBookings$ = createEffect(() => 
        this.actions$.pipe(
            ofType(BookingActions.loadBookings),
            switchMap(() => 
                from(this.bookingService.getBookings()).pipe(
                map((bookings) => BookingActions.loadBookingsSuccess({ bookings: bookings}))
                )
            )
        )
    )
}

booking.reducer.ts

import { createReducer, on } from "@ngrx/store";
import { Booking } from "../model/booking.model";
import { loadBookings, loadBookingsSuccess } from "./booking.actions";

export interface BookingState {
    bookings: Booking[];
    error: string;
    status: 'pending' | 'loading' | 'error' | 'success';
}

export const initialState: BookingState = {
    bookings: [],
    error: "",
    status: 'pending',
}

export const bookingReducer = createReducer(
    //Supply initial state
    initialState,
    //Trigger loading bookings
    on(loadBookings, (state) => ({ ...state, status: 'loading' as const })),
    on(loadBookingsSuccess, (state, { bookings }) => ({
        ...state,
        bookings: bookings,
        error: '',
        status: 'success' as const,
    }))
)

booking.selector.ts

import { createSelector } from "@ngrx/store";
import { AppState } from "./app.state";
import { BookingState } from "./booking.reducer";

export const selectBookings = (state: AppState) => state.bookings;
export const selectAllBookings = createSelector(
    selectBookings,
    (state: BookingState) => state.bookings
);

app.modules.ts

import { NgModule, isDevMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { EffectsModule } from '@ngrx/effects';
import { BookingTableComponent } from './booking-table/booking-table.component';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { HttpClientModule } from '@angular/common/http';
import { bookingReducer } from './store/booking.reducer';
import { BookingEffects } from './store/booking.effects';

@NgModule({
  declarations: [
    AppComponent,
    BookingTableComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    StoreModule.forRoot({ bookings: bookingReducer }, {}),
    StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }),
    EffectsModule.forRoot([BookingEffects]),
    HttpClientModule
  ],
  providers: [
    provideAnimationsAsync()
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

booking.component.ts

import { Component, OnInit } from '@angular/core';
import { BookingService } from '../booking.service';
import { loadBookings } from '../store/booking.actions';
import { Store } from '@ngrx/store';
import { Booking } from '../model/booking.model';
import { selectAllBookings } from '../store/booking.selector';

@Component({
  selector: 'app-booking-table',
  templateUrl: './booking-table.component.html',
  styleUrl: './booking-table.component.css'
})
export class BookingTableComponent implements OnInit {
  //Error here
  public allBookings = this.store.select(selectAllBookings);

  constructor(private store: Store) {

  }

  ngOnInit(): void {
    this.store.dispatch(loadBookings());
  }

}

解决方案

错误原因是组件中注入的Store未指定泛型类型AppState,TypeScript无法识别全局状态的结构,导致与选择器的类型不匹配。

修改booking.component.ts:

  1. 导入AppState接口
  2. 在构造函数中给Store指定泛型<AppState>

修改后的代码:

import { Component, OnInit } from '@angular/core';
import { loadBookings } from '../store/booking.actions';
import { Store } from '@ngrx/store';
import { Booking } from '../model/booking.model';
import { selectAllBookings } from '../store/booking.selector';
// 新增导入
import { AppState } from '../store/app.state';

@Component({
  selector: 'app-booking-table',
  templateUrl: './booking-table.component.html',
  styleUrl: './booking-table.component.css'
})
export class BookingTableComponent implements OnInit {
  public allBookings = this.store.select(selectAllBookings);

  // 指定Store泛型为AppState
  constructor(private store: Store<AppState>) {

  }

  ngOnInit(): void {
    this.store.dispatch(loadBookings());
  }

}

修改后TypeScript可正确识别全局状态结构,选择器与store类型匹配,错误即可消除。

内容的提问来源于stack exchange,提问作者Strugglingperson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:02:17