具有泛型类型的Redux工具箱createAction



我正在尝试使用Redux工具包createAction来生成一个采用泛型类型的操作。类型如下。

export interface ObjectArray {
externalId: string
}
export interface CarFilters {
arrayType: string[];
objectType: ObjectArray[];
}
export type FilterOptionValue = string | number;
export type FilterMapValue = FilterOptionValue[] | string;
export interface ShipFilters {
[key: number]: FilterMapValue;
}
type AppliedFiltersType = {
cars: CarFilters;
ships: ShipFilters;
}
type PathValue<T extends object, K extends keyof T = keyof T> = T[K] extends unknown ? T[K] : never;
export type AssingValueType<
Category extends keyof AppliedFiltersType = keyof AppliedFiltersType, 
Key extends keyof PathValue<AppliedFiltersType, Category> = keyof PathValue<AppliedFiltersType, Category>
> = {
category: Category,
filterKey: Key
value: PathValue<AppliedFiltersType[Category], Key>;
}

减速器和动作

import { createAction, createReducer } from "@reduxjs/toolkit";
import { AssingValueType, AppState } from "./types";
export const updateAppliedFilterValue = createAction<AssingValueType>(
"UPDATE_APPLIED_FILTER_VALUE"
);
const initialState = {
appliedFilters: {
cars: {
arrayType: [],
objectType: []
},
ships: {}
}
} as AppState;
const reducerCreator = createReducer(initialState, (builder) => {
builder.addCase(updateAppliedFilterValue, (state, action) => {
state.appliedFilters[action.payload.category] = action.payload.value;
});
});
export default reducerCreator;

目的是对操作参数进行严格的类型检查,这样就不能用不一致的类型调用它。

例如

更新AppliedFilterValue({类别:'汽车',filterKey:1,值:3})

应标识为ts编译器的错误。

纯功能如以下作品

const updateFilterValues = <Category extends keyof AppliedFiltersType, Key extends keyof PathValue<AppliedFiltersType, Category>>(params: AssingValueType<Category, Key>) => {
return params;
}

但我不清楚如何使用createAction创建生成操作我在创建推断泛型类型的操作时遇到了问题。

Codesandbox链接

您遇到的问题似乎与AssigningValueType的定义密切相关。

解决方案:

export type AssingValueType = {
[Category in keyof AppliedFiltersType]:
{ category: Category } & {
[Key in keyof AppliedFiltersType[Category]]: {
filterKey: Key,
value: PathValue<AppliedFiltersType[Category], Key>
}
}[keyof AppliedFiltersType[Category]]
}[keyof AppliedFiltersType]

讲解员AssingValueType是判别并集类型,Category是AppliedFiltersType的关键字,又称'ships' | 'cars'

对于每个潜在类别,我们也以类似的方式定义filterKeyvalue可以相对于Category和Key进行定义。

&类型的交集运算符用于将{filterKey,value}与{category}合并。

最后也是最重要的一步是{[Category in keyof AppliedFiltersType]: ...}[keyof AppliedFiltersType]其提取AppliedFiltersType的每个键的并集类型。

简而言之。。。{ships: {category: 'ships', ...}, cars: {category: 'cars', ...}}变为{category: 'cars' ...} | {category: 'ships'}

关于你最初的担忧,createAction应该像你想要的那样发挥魅力。

相关内容

  • 没有找到相关文章

最新更新