新手求教:TypeScript下如何创建匹配NgRx的MemoizedSelector接口的函数?
问题与解决方案
原NgRx接口定义
export interface MemoizedSelector< State, Result, ProjectorFn = DefaultProjectorFn<Result> > extends Selector<State, Result> { release(): void; projector: ProjectorFn; setResult: (result?: Result) => void; clearResult: () => void; }
应对复杂TypeScript函数/接口实现的实用技巧与工具
利用编辑器的类型提示与自动补全
用VS Code这类支持TypeScript的编辑器,开启strict模式。先声明变量的目标类型为MemoizedSelector<你的State类型, 结果类型>,比如:interface AppState { user: { name: string } } const mySelector: MemoizedSelector<AppState, string> = {};编辑器会直接标红缺失的属性(
release、projector等),并提示每个属性的类型要求,跟着补全即可,不用反复查关联类型。复用NgRx官方辅助函数
NgRx本身提供了createSelector、createFeatureSelector等工具函数,它们返回的对象天然符合MemoizedSelector接口,完全没必要从零手动实现。比如:import { createSelector } from '@ngrx/store'; const selectAppState = (state: AppState) => state; const selectUserName = createSelector(selectAppState, state => state.user.name);这样得到的
selectUserName就是标准的MemoizedSelector实例,自带所有要求的方法与属性。用Partial类型过渡实现
如果必须手动实现,先创建Partial<MemoizedSelector<...>>类型的临时对象,TS会提示你补全所有必填项,完成后再断言为完整类型:const tempSelector: Partial<MemoizedSelector<AppState, string>> = { projector: (state) => state.user.name, release: () => { /* 这里写释放缓存的逻辑 */ }, setResult: (result?) => { /* 手动设置结果的逻辑 */ }, clearResult: () => { /* 清除缓存结果的逻辑 */ } }; const mySelector = tempSelector as MemoizedSelector<AppState, string>;参考NgRx官方源码实现
直接看NgRx内部如何实现MemoizedSelector的实例(比如createSelector的返回逻辑),官方实现已经处理了缓存、方法封装等细节,照搬逻辑比自己试错高效得多。用typeof提取复用类型
如果已有合法的MemoizedSelector实例,用typeof提取它的类型,后续创建同类实例时直接复用:// 假设已有一个合法的selector实例 const existingSelector = createSelector(selectAppState, state => state.user.name); type UserNameSelector = typeof existingSelector; // 新实例直接复用这个类型 const anotherUserNameSelector: UserNameSelector = { /* 补全属性 */ };
内容的提问来源于stack exchange,提问作者wonderful world
相关产品推荐
相关产品推荐

