【发布时间】:2021-08-16 16:55:15
【问题描述】:
我很难在 redux reducer 中处理这个打字稿错误。我创建了一个简化版本,如下所示来复制问题。
export const CATEGORY_TYPES = ['cars', 'ships'] as const;
export type CategoryTypes = typeof CATEGORY_TYPES[number]
export interface ObjectArray {
externalId: string
}
export interface CarFilters {
arrayType: string[];
objectType: ObjectArray[];
}
export interface AppState {
appliedFilters: {
cars: CarFilters;
ships: {
[filter: string]: string[];
};
};
}
export interface AssignValue {
category: CategoryTypes;
key: string;
value: string[] | ObjectArray[];
}
const initialState = {
appliedFilters: {
cars: {
arrayType: [],
objectType: [],
},
ships: {},
},
} as AppState;
const assignValue = (params: AssignValue)=>{
initialState.appliedFilters[params.category][params.key] = params.value;
}
我收到以下错误
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'CarFilters | { [filter: string]: string[]; }'.
No index signature with a parameter of type 'string' was found on type 'CarFilters | { [filter: string]: string[]; }'.
AssignValue 是 reducer (redux-toolkit) 中代码的复制。问题似乎是[params.key]。但是两个对象都有字符串键。
打字稿游乐场sample
这里可能有什么问题。
使用答案中的建议进行更新,因此以下工作完美。
export const CATEGORY_TYPES = ['cars', 'ships'] as const;
export type CategoryTypes = typeof CATEGORY_TYPES[number];
export interface ObjectArray {
externalId: string
}
export interface CarFilters {
arrayType: string[];
objectType: ObjectArray[];
}
export interface ShipFilters {
[filter: string]: string;
}
export interface AppState {
appliedFilters: {
cars: CarFilters;
ships: ShipFilters;
};
}
const initialState = {
appliedFilters: {
cars: {
arrayType: [],
objectType: [],
},
ships: {},
},
} as AppState;
type AppStateFilters = AppState["appliedFilters"]
type PathValue<T extends object, K extends keyof T> = T[K] extends unknown ? T[K] : never
function assignValue<
Category extends keyof AppStateFilters,
Key extends keyof PathValue<AppStateFilters, Category>
>(params: {
category: Category,
key: Key,
value: PathValue<AppStateFilters[Category], Key>
}): void {
initialState.appliedFilters[params.category][params.key] = params.value;
}
然后我尝试将assignValue函数的类型定义为单独的类型(实际上这是一个redux状态更新场景的简化示例,所以我需要为action单独定义传递参数类型。)而这次我想用各自的值( CarFilters 或 ShipFilters )更新整个类别(汽车或船舶)
// It works type defined with the function
const updateCategoryFilterV1 = <
Category extends keyof AppStateFilters,
Key extends PathValue<AppStateFilters, Category> = PathValue<AppStateFilters, Category>
>(params: {
category: Category,
value: Key
})=>{
initialState.appliedFilters[params.category] = params.value;
}
// But when type is extracted, it does not.
type UpdateAppliedFilterType<Category extends keyof AppStateFilters = keyof AppStateFilters,
Filter extends PathValue<AppStateFilters, Category> = PathValue<AppStateFilters, Category>> = {
category: Category,
filter: Filter
}
const updateCategoryFilterV2 = (params: UpdateAppliedFilterType) => {
initialState.appliedFilters[params.category] = params.filter
}
错误
Type 'CarFilters | ShipFilters' is not assignable to type 'CarFilters & ShipFilters'.
Type 'CarFilters' is not assignable to type 'CarFilters & ShipFilters'.
Type 'CarFilters' is not assignable to type 'ShipFilters'.
Index signature is missing in type 'CarFilters'.(2322)
【问题讨论】:
标签: typescript redux redux-toolkit