我正在try 创建一个Reducer函数,它允许我们推断有效负载中允许的属性和值,目前这是有效的,如果调度中的type属性被更改,它将只允许传递与ToolMap相关联的值,如果在有效负载中传递错误的名称值,则将抛出错误.

问题出现在削减器的接收端,即action.有效负载不能正确地推断name属性是否正确,它总是认为它是一个联合类型CursorToolNameDrawingToolName.这让我感到有点困惑,因为当有效负载到达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'
}})

推荐答案

以下几个方法可以解决这个问题:

const reducer = <T extends ToolCategory, S extends ToolState>(
    state: S,
    action: ToolAction<T>
): S => {
    switch(action.type){
        case 'CursorTools': {
            return {
                ...state,
                CursorTools: {
                    name: action.payload.name
                }
            }
        }
    }

    return state;
}

Typescript相关问答推荐

在控制器中使用@ DeliverGuards时实现循环依赖项时未定义的依赖项

具有条件通用props 的react 类型脚本组件错误地推断类型

排序更改数组类型

为什么在将条件返回类型的字符串赋给数字时没有类型错误?

使用新控制流的FormArray内部的Angular FormGroup

TypScript如何在 struct 上定义基元类型?

angular 17独立使用多个组件(例如两个组件)

是否可以根据嵌套属性来更改接口中属性的类型?

基于键的值的打字动态类型;种类;

如何使我的函数专门针对联合标记?

ANGLE独立组件布线错误:没有ActivatedRouting提供程序

如何将v-for中的迭代器编写为v-if中的字符串?

重载函数的T helper参数

如何将TS泛型用于react-hook-form接口?

创建Angular 为17的动态形状时出错

类型';字符串|数字';不可分配给类型';未定义';.类型';字符串';不可分配给类型';未定义';

如何按属性或数字数组汇总对象数组

在Cypress中,是否可以在不标识错误的情况下对元素调用.Click()方法?

换行TypeScript';s具有泛型类型的推断数据类型

如何在Vuetify 3中导入TypeScript类型?