TypeScript中Reducer根据传入Key推断值类型的问题及异常
问题场景
实现一个用于更新slice中userData任意属性的Reducer函数时,遇到类型校验问题。该函数接收包含key和value的数组:key必须是TUserData的键类型,value需要匹配该key在TUserData中对应的类型。
初始代码
Reducer实现
updateUserProp(state, action: { payload: [keyof TUserData, TUserData[keyof TUserData]]; type: string }) { const [key, value] = action.payload; state.userData![key] = value; },
TUserData类型定义
type TUserData = { email: string; uid: string; username: string; firstName: string; lastName: string; phoneNumber: string; createdOn: string; initials?: string; status: EUserStatus; profilePhoto?: string; chats?: { [x: string]: EChatStatus }; messagesSent?: { [x: string]: boolean }; }
报错信息
Type 'string | { [x: string]: EChatStatus; } | { [x: string]: boolean; } | undefined' is not assignable to type 'string & EUserStatus & (WritableDraft<{ [x: string]: EChatStatus; }> | undefined) & (WritableDraft<{ [x: string]: boolean; }> | undefined)'. Type 'undefined' is not assignable to type 'string & EUserStatus & (WritableDraft<{ [x: string]: EChatStatus; }> | undefined) & (WritableDraft<{ [x: string]: boolean; }> | undefined)'.
尝试的解决方案
通过泛型改造解决了初始报错,代码如下:
function updateUserProp<K extends keyof TUserData>( state: { userData?: TUserData }, action: { payload: [K, TUserData[K]]; type: string; }, ) { const [key, value] = action.payload; state.userData![key] = value; }
新问题
该函数单独调用时类型校验正常,但作为Reducer使用时,会允许为key分配错误类型的值。例如执行dispatch(authActions.updateUserProp(["status", undefined]))不会触发类型报错,但直接调用updateUserProp({}, { payload: ["status", undefined]})时,会正常触发类型错误提示。
内容的提问来源于stack exchange,提问作者kokiqn

