我正在try 创建一个Reducer函数,它允许我们推断有效负载中允许的属性和值,目前这是有效的,如果调度中的type属性被更改,它将只允许传递与ToolMap相关联的值,如果在有效负载中传递错误的名称值,则将抛出错误.
问题出现在削减器的接收端,即action.有效负载不能正确地推断name属性是否正确,它总是认为它是一个联合类型CursorToolName或DrawingToolName.这让我感到有点困惑,因为当有效负载到达Switch语句中的Case时,它应该始终是正确的类型.
type ToolCategory = 'CursorTools' | 'DrawingTools'
type CursorToolName = 'Cursor' | 'Measure'
type DrawingToolName = 'Brush' | 'Pencil'
type ToolMap = {
CursorTools: CursorToolName;
DrawingTools: DrawingToolName
}
interface ToolState {
CursorTools: Tool<'CursorTools'>
DrawingTools: Tool<'DrawingTools'>
}
interface ToolAction<T extends ToolCategory>{
type: T;
payload: Tool<T>
}
interface Tool<T extends ToolCategory> {
name: ToolMap[T];
onEnter?: () => void;
}
const reducer = <T extends ToolCategory>(
state: ToolState,
action: ToolAction<T>
): ToolState => {
switch(action.type){
case 'CursorTools': {
return {
...state,
CursorTools: {
// This doesn't infer that the payload.name is of correct type
name: action.payload.name
}
}
}
}
return state;
}
// This infers the name in the payload we can pass, and we can never pass the wrong value
reducer({CursorTools: {name: 'Cursor'}, DrawingTools: {name: 'Brush'}
}, {type: 'CursorTools', payload: {
name: 'Cursor'
}})