Angular NgRx报错:类型'{}'缺少必填属性'todos'
解决NgRx中Store.select()的TS2769类型不兼容错误
问题根源
注入Store时未指定自定义的AppState类型,Angular默认推断为Store<{}>,而你的SelectAllTodos Selector依赖完整的AppState结构(包含必填的todos属性),导致类型校验失败。
修复步骤
1. 确认AppState类型定义正确
确保根状态接口明确包含todos属性,且类型与Reducer输出匹配:
// app.state.ts import { Todo } from './todo.model'; export interface AppState { todos: Todo[]; // 与你的todos Reducer返回的类型一致 }
2. 组件中注入带泛型的Store
在todo-list组件中,注入Store时指定AppState泛型,让TypeScript识别Store的完整状态结构:
// todo-list.component.ts import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { AppState } from '../app.state'; import { SelectAllTodos } from '../todo.selectors'; @Component({ selector: 'app-todo-list', templateUrl: './todo-list.component.html' }) export class TodoListComponent { todos$ = this.store.select(SelectAllTodos); constructor(private store: Store<AppState>) { } // 指定AppState泛型 }
3. 检查Selector的状态切片关联
确保Selector基于AppState的todos切片创建,避免类型不匹配:
// todo.selectors.ts import { createSelector } from '@ngrx/store'; import { AppState } from './app.state'; // 定义获取todos切片的基础Selector const selectTodosSlice = (state: AppState) => state.todos; // 基于切片创建全量Todo的Selector export const SelectAllTodos = createSelector( selectTodosSlice, (todosSlice) => todosSlice // 根据Reducer逻辑返回对应数据 );
4. 验证Root Store的Reducer注册
确保StoreModule.forRoot中注册Reducer的key与AppState的todos属性名完全一致:
// app.module.ts import { StoreModule } from '@ngrx/store'; import { todosReducer } from './todo.reducer'; import { AppState } from './app.state'; @NgModule({ imports: [ StoreModule.forRoot<AppState>({ todos: todosReducer // key必须和AppState中的属性名完全相同 }) ] }) export class AppModule { }
额外说明
TS2769错误本质是TypeScript严格类型校验:调用store.select(SelectAllTodos)时,Selector期望接收包含todos属性的AppState,但默认的Store<{}>不包含该属性,因此触发类型不兼容报错。通过指定Store的泛型类型,TypeScript就能正确识别状态结构,解决该错误。
内容的提问来源于stack exchange,提问作者onTheInternet
相关产品推荐
相关产品推荐

